Skip to main content
Glama

Zuar Portal — MCP Server

Permite que Claude gestione tu Zuar Portal (zPortal) por ti — crea bloques HTML, construye páginas, gestiona fuentes de datos, consultas, temas y usuarios, explora datos reales y mantén un historial versionado en git y reversible de cada cambio, todo a través de lenguaje natural.

release MCP Zuar Portal node one-click install license


Un servidor MCP que expone la API REST y de autenticación de Zuar Portal a cualquier cliente MCP (Claude Desktop, Claude Code, …). Convierte «hazme un panel de ventas» en la secuencia correcta de llamadas autenticadas — descubrir fuentes de datos → escribir una consulta guardada → crear un bloque HTML validado → vincularlo → colocarlo en una página — con guía de creación integrada, seguridad de escritura por capas y un historial reversible.

[!TIP] Instalación (Claude Code) — clónalo, compílalo y regístralo:

git clone https://github.com/zuarbase/Zuar-Portal-MCP-Public.git ~/zuar-portal-mcp
cd ~/zuar-portal-mcp && npm install && npm run build
claude mcp add zuar-portal --scope user -- node ~/zuar-portal-mcp/dist/index.js

Luego haz cd a una carpeta de proyecto y ejecuta /portal-setup para conectarlo a un portal. Detalles ↓

Sin terminal (Claude Desktop): descarga zuar-portal-mcp.mcpb desde la última versión y haz doble clic en él. Detalles ↓

De un vistazo

flowchart TB
    CD["<b>MCP Client</b><br/>Claude Desktop · Claude Code · any MCP client"]
    CD -- "JSON-RPC / stdio" --> S

    subgraph server["zuar-portal-mcp server"]
        direction TB
        S["index.ts → buildServer()"]
        S --> BT["🧱 <b>Block tools</b><br/>typed authoring + place_blocks"]
        S --> RT["📦 <b>Resource tools</b><br/>generic CRUD · 18 kinds (blocks included)"]
        S --> AT["⚡ <b>Action tools</b><br/>query · profile · users · config"]
        S --> VC["🕓 <b>Version-control tools</b><br/>snapshot · history · diff · restore"]
        S --> EL["🪄 <b>Setup &amp; design</b><br/>configure_project · synthesize_theme"]
        G{{"🛡️ <b>Safety &amp; integrity gates</b><br/>write-domain · structure · refs · impact · SQL"}}
        BT & RT & AT & VC & EL --> G
    end

    G --> HTTP["portalClient.ts<br/>login · X-Api-Key · retry · circuit breaker"]
    HTTP -- "/api + /auth · HTTPS" --> P[("Zuar Portal")]
    BT -. "mirrors every content write" .-> GIT[("git VC repo<br/>revertible")]

    classDef gate fill:#fde68a,stroke:#b45309,color:#000;
    class G gate

Cada escritura está etiquetada con un dominio de riesgo y pasa las compuertas de seguridad antes de que nada llegue al portal; cada escritura de contenido con éxito se replica en un repositorio git para que pueda revertirse.

Related MCP server: LaunchNotes MCP Server

Contenido

¿Trabajas en el servidor en lugar de con él? Consulta CONTRIBUTING.md.

[!NOTE] 📚 Documentación completa en docs/ — guía rápida de 5 minutos, instalación y configuración, una referencia generada de las 40 herramientas, creación de bloques, el sistema de diseño, el control de versiones, la API zPortal dentro de un bloque, el ecosystem de agentes y enrutamiento de modelos, la limitación de herramientas, las compuertas de seguridad y la resolución de problemas.

Aspectos destacados

🧰 Una superficie uniforme (v3.0.0)

Un único modelo para todo — los bloques son un tipo de registro validado, una sola colocación declarativa place_blocks, dry_run uniforme en cada escritura, listas paginadas y nuevas lecturas (find_resource, get_references, vc_diff). Cambio importante; PORTAL_COMPAT_TOOLS=1 conecta con los nombres v2 anteriores.

⌨️ Instala una vez, úsalo en todas partes

Clona y compila + claude mcp add … -- node …/dist/index.js, y luego /portal-setup por proyecto. O un .mcpb para Claude Desktop — sin terminal.

🧱 Creación validada

Los bloques HTML se comprueban con herramientas basadas en reglas (create_block/update_block/validate_block) — y create_resource (block) pasa por el mismo validador por tipo antes de llegar al nodo central del registro, por lo que se detectan errores tontos antes de tocar el portal.

🏢 Multi-portal, multi-repo (v2.4.0)

Una instalación usa un portal y un repo git distintos por carpeta a glanz de ./.zuar-portal/config.json.

🪄 Configuración en el navegador sin JSON, sin clave en en modelo

configure_project muestra un formulario web de bucle local — escribes la clave de API en el navegador, para que nunca pase por la IA; valida en vivo y escribe un .config15 config0600. Se resort a la información y argumentos. La indicación design_intake te guíe por la personalización del tema y ejecuta synthesize_theme.

🤝 Un equipo de agentes

En Claude Code, un pipeline gated de subagentes especializados (build → style → responsive → debug → adversary → advisor) crea bloques para ti — cada uno con un modelo de tamaño adecuado.

🔒 Seguridad empresarial (v2.5–2.6)

Escritura por dominios de riesgo, delimitación de herramientas con privilegios, compuertas de integridad estructural y referencial, análisis de impacto previo al borrado y un registro de auditoría opcional.

🕓 Historial reversible (v2.2.0)

Cada escritura de contenido se espeja a un repositorio git — restaura cualquier cambio con restore_resource.


Qué puede hacer Claude con él

40 herramientas — un única superficie uniforme ("un recurso es un recurso") en apostas de 11 grupos de capacidad. La referencia completa por herramienta se genera. directamente desde el servidor en vivo (npm run gen:docs, no pueden desfasar): docs/03 · Referencia de herramientas.

[!IMPORTANT] ¿Actualizas desde 2.x? v3.0.0 es un rediseño de la API no compatible (48 → 37 herramientas). Cada nombre v2 eliminado se .map a una primitiva v3 — consulta CHANGELOG.md. Define PORTAL_COMPAT_TOOLS=1 para registrar temporalmente los nombres antiguos como alias obsoletos que reenvían a los mismos controladores v3 controlados.

🧱 Herramientas de bloque — tipadas y validadas

Los bloques forman parte ahora de un tipo de recurso de primera clase: lista, vet, and delete them con la herramienta genérica de recursos (resource: "block"), y las reglas de autoría de bloque se aplican con un validador en función del recurso en el nodo de entrada del registro — create_resource (block) se valida exactamente igual que create_block. Los frentes tipados siguen existiendo para una authoría ergonómica:

Herramienta

Qué hace

validate_block

Ejecuta las reglas de authoría contra un bloque de datos datos sin escribirlo — díta hasta que se ha validez.

create_block

Crea un bloque HTML (validado según las reglas).

update_block

Actualiza un bloque HTML — lo completó sobre el bloque actual para que los campos no modificados se cambien.

Entrada de archivo [4.2.0] — create_block, update_block y validate_block admiten html_file y css_file. El servidor es quien lee los bytes, de modo que un modelo nunca los maneja directamente. Reescribir un bloque grande llamando a una herramienta no es copiar, sino retranscribir: gasta tokens y normaliza caracteres silenciosamente (una raya que parece un guión dentro de una clase de caracteres cambia lo que el patrón detecta — y le pasa a revisión). En su lugar dal una ruta, edita el archivo en el sitio, y así solo se transcribe lo cambiado. Todas la compuertas actúan igual en una y otra case. Las lecturas se aplican a , y PORTAL_FILE_ROOTS. | `bind_block_query` | Enlaza un bloque a una fuente de datos/query (crea automáticamente la consulta); define `ui_queries`. | | `place_blocks` | Una sola primitiva de colocación — agregar, actualizar, ocultar o quitar bloques de un grid en un instante. mode: "merge" agrega/actualiza (y respeta remove: [...]); mode: "replace" + confirm: true hace la página exactamente la lista indicada y conserva las grid.layouts y flags de ocultación ya personalizadas. |

Pass resource de operación/body/id. Contains una API describe_resource para campos de cada recurso, los campos obligatorios, verbos válidos. Read new resources via pair estimaciones.

Herramienta

Qué hace

describe_resource

Lista recursos, o describe uno (campos, verbos, dominio).

list_resource

Lista registros — siempre devuelve el envoltorio paginado {total, offset, limit, returned, truncated, records} (por defecto limit 100, máximo 500).

get_resource

Obtiene un registro por id — p. ej. resource: "user", id: "me" para el perfil del usuario actual.

find_resource

Busca por nombre (subcadena sin distinción de mayúsculas, o id exacto) entre tipos — opcional kinds, tag, limit/offset; por defecto todos los tipos no administradores.

get_references

Consulta de dependencias de solo lectura, en ambas direcciones: dependents (quién se rompe si esto se elimina — el mismo análisis que ejecuta la compuerta de eliminación) y references (a qué apunta este registro, cada uno marcado exists: false cuando está colgante).

create_resource

Crea un registro (con compuerta de escritura por dominio; validadores por tipo — los bloques obtienen las reglas completas de autoría).

update_resource

Actualiza un registro (fusionado sobre el actual; con compuerta de escritura).

delete_resource

Elimina un registro (con compuerta de escritura; análisis de impacto previo a la eliminación; confirm/force).

validate_portal

Barrido de solo lectura para registros malformados, referencias colgantes y SQL arriesgado.

Recursos cubiertos: block, layout (páginas), datasource, query, db_modification, partial, theme, snippet, translation, dashboard, tag, user, group, permission, access_policy, api_key, credential, system.

Cada herramienta de escritura acepta dry_run: true — se ejecutan todas las compuertas (dominio, estructura, reglas por tipo, referencias, impacto), no se escribe nada, y la respuesta lleva applied: false más lo que se habría escrito.

Tool

What it does

Domain

profile_datasource

Estadísticas por columna (tipo, valores distintos, min/max) más filas de muestra sin procesar (sample.columns / sample.rows; sample_rows por defecto 10, máximo 50) para diseñar filtros y gráficos sobre columnas reales.

read

execute_query

Ejecuta una consulta guardada por id y devuelve resultados (límite de filas opcional).

read

run_db_modification

Ejecuta una escritura de BD guardada por nombre. Requiere confirm: true.

data

change_password

Cambia la contraseña del usuario actual.

admin

get_user_access

Lee la pertenencia a grupos y los permisos de un usuario en una sola llamada.

read

set_user_access

Reemplaza los grupos y/o permisos de un usuario: cada lista proporcionada es un reemplazo completo; requiere confirm: true, admite dry_run.

admin

get_config / update_config

Lee / establece la configuración del portal por ruta.

read / admin

get_version

Versión del portal + información (comprobación de capacidades).

read

get_rules

Muestra las reglas activas de creación de bloques.

read

naming

La gramática de nombres scope · kind · subject: action: "suggest" propone nombres, action: "parse" los descompone.

read

check_connection

Empieza aquí: confirma la conexión en un solo viaje de ida y vuelta autenticado: portal, versión, con quién has iniciado sesión, estado de vinculación y postura de escritura, en ~160 caracteres. Las credenciales incorrectas devuelven el motivo y la solución, no un falso éxito (siempre disponible).

read

get_capabilities

Informa de la postura actual: grupos de herramientas habilitados/deshabilitados, seguridad de escritura, estado de VC + auditoría, y la configuración activa (portal / repositorio VC, secretos redactados) bajo su clave config (siempre disponible).

read

get_metrics

Conteo de llamadas por herramienta, tasa de error, latencia, tiempo de actividad, estado del interruptor (siempre disponible).

read

configure_project

Conecta esta carpeta a un portal. Por defecto abre una página de configuración de bucle local (la clave API se escribe en el navegador, nunca a través del modelo), valida en vivo, escribe una configuración 0600; recurre a la elicitación y luego a los argumentos (pasa ui:false, o portal_url + api_key + user_id). También recopila interruptores de seguridad de escritura + alcance de acceso + VC de GitHub opcional. Fija la carpeta al portal para que las escrituras no puedan cruzar portales; escribe ./.zuar-portal/config.json + design.md + un bloque CLAUDE.md gestionado.

setup

reload_config

Vuelve a leer la configuración desde el disco (proyecto/paquete/entorno) sin reiniciar; restablece la sesión del portal.

setup

synthesize_theme

Síntesis de tema pura: preferencias (± una obtención de color de sitio web protegida contra SSRF) → un mapa de tokens más la llamada exacta a create_resource (create_with); no crea nada por sí misma. Orquestada por el prompt design_intake.

design

migration_preflight

Auditoría de migración de solo lectura: cada bloque clasificado por función, todos los campos con código escaneados (consciente de comentarios/cadenas), colocación mediante layouts/partials/snippets, barrido de origen codificado, preflight de consultas vinculadas, lista de verificación de sonda de navegador.

migration

repair_query_metadata

Actualiza los metadatos de columna almacenados de una consulta guardada desde una ejecución en vivo: SQL intacto, dry-run por defecto, ida y vuelta verificado.

migration

El perfil del usuario actual es ahora un CRUD de recurso simple: get_resource / update_resource con resource: "user", id: "me". El alcance de la migración guiada es el prompt migration_kickoff (ver Prompts más abajo).

Herramienta

Qué hace

vc_status

Muestra si VC está configurado y el estado del repositorio.

snapshot_portal

Confirma el estado completo actual del portal en el repositorio git: un punto de control duradero.

vc_log

Muestra el historial de confirmaciones de los cambios de contenido.

vc_diff

Diff unificado entre dos versiones confirmadas, con alcance por registro (resource + id) o de todo el repositorio; por defecto compara la confirmación anterior que tocó el registro con HEAD. Inspecciona antes de restore_resource: una reversión nunca es a ciegas.

restore_resource

Restaura un recurso a una versión confirmada anterior.

Consulta docs/07 · Control de versiones.

Recursos (zportal://guide/*): orientación de autoría que Claude lee antes de construir, para que los bloques sigan las convenciones de zPortal incluso en una máquina nueva: block-structure, currentblock, zportal-api, charting, conventions, design-system, visual-verification, migration-1.18, loading-overlay, migration-playbook y block-performance.

Prompts: los flujos de trabajo guiados ahora viven aquí en lugar de en la superficie de la herramienta (9): zuar_portal_start (el abridor de sesión más económico: confirma la conexión en una sola llamada, informa una línea y pregunta qué sigue), zuar_portal_quickstart (orientar → enrutar), create_zportal_block (descubrir → construir → crear), setup_zuar_project (conectar esta carpeta, enruta a configure_project), migrate_block_to_118 (un bloque heredado → el ciclo de vida 1.18), add_loading_overlay (el spinner autorizado + desvanecimiento), block_perf_pass (la auditoría de rendimiento con grandes conjuntos de datos: medir → recortar SELECT * → precarga de la librería de gráficos → timeouts honestos de 60 s), design_intake (temática guiada: recorre marca/sitio web/densidad/radio, impulsa synthesize_theme y luego crea el tema mediante create_resource) y migration_kickoff (alcance de migración guiado: agrupa las decisiones de alcance, escribe .zuar-portal/migration-scope.json y luego ejecuta migration_preflight).


El ecosistema de agentes de Claude Code

Cuando este repositorio es tu directorio de trabajo de Claude Code, las herramientas MCP vienen con un equipo de especialistas en .claude/. No manejas create_block/bind_block_query a mano: describes lo que quieres y un pipeline con compuertas construye, estiliza, refuerza y revisa. Guía completa: docs/13 · Agentes y flujos de trabajo.

El pipeline de bloques

Los bloques nunca se publican en bruto. Una especificación fluye a través de compuertas de calidad, cada una un subagente enfocado:

flowchart LR
    spec([spec]) --> B["🏗️ builder"] --> St["🎨 stylist"] --> R["📱 responsive"] --> D["🔧 debugger"]
    D --> A{"🚨 adversary<br/><b>CODE GATE</b>"}
    A -- "blocking (≤2 rounds)" --> D
    A -- "clean" --> V{"👁️ visual<br/><b>GATE</b>"}
    V -- "blocking (≤2 rounds)" --> D
    V -- "clean / skipped" --> Ad["🧭 advisor"] --> ship([ship ✅])

    classDef gate fill:#fde68a,stroke:#b45309,color:#000;
    classDef ro fill:#dbeafe,stroke:#1d4ed8,color:#000;
    class A,V gate
    class Ad ro

El adversario (compuerta) pone a prueba el bloque y demuestra cada hallazgo con evidencia; mientras devuelva hallazgos bloqueantes, el pipeline vuelve al depurador. La compuerta visual (el adversario con ojos de navegador) entonces abre el bloque renderizado en Claude for Chrome: captura de pantalla, consola, red; y un renderizado en blanco, un error de consola, datos de muestra no en vivo o un desbordamiento también devuelven al depurador; es de mejor esfuerzo y se omite con una nota cuando la extensión no está conectada o el bloque no está en una página. El asesor pregunta: "¿es este el bloque correcto?" Todas las compuertas son de solo lectura: no llevan herramientas de escritura y físicamente no pueden mutar el portal (navegar/capturar pantallas es de solo lectura). Más allá de los seis agentes del pipeline, cuatro especialistas manejan trabajos más amplios: portal-data-expert, portal-theme-designer, portal-bulk-operator (primero instantánea) y portal-onboarding.

Ver el portal (Claude for Chrome)

Cada compuerta anterior razona sobre un bloque a partir de su código y filas de consulta, pero un bloque puede validar, vincular y aun así renderizar en blanco, lanzar un error de consola en tiempo de ejecución, desbordar su celda de cuadrícula o mostrar silenciosamente su respaldo de muestra codificado en lugar de datos en vivo. Con la extensión Claude for Chrome conectada, los agentes pueden ver el portal: abrir la página, capturar el bloque y leer la consola/red del navegador, para depuración visual y una aprobación visual final.

  • Registrado en la configuración. configure_project pregunta si usas Claude for Chrome y almacena browser.claudeInChrome en ./.zuar-portal/config.json; get_capabilities lo informa.

  • Se usa donde vale la pena. El depurador mira antes de adivinar; el adversario es dueño de la compuerta visual; el estilista y el especialista en responsive capturan su trabajo (este último recorre anchos con resize_window); el asesor verifica que se lea de un vistazo.

  • Advertencia de inicio de sesión. El MCP se autentica con una clave API, pero el navegador necesita una sesión iniciada: para ver páginas privadas debes haber iniciado sesión en tu portal en Chrome. El MCP no puede iniciar sesión por ti.

  • Elegante por diseño. ¿Sin extensión, o el bloque no está en una página? Cada agente recurre a la revisión solo con código y lo indica. La doctrina vive en el recurso zportal://guide/visual-verification.

Comandos de barra

Comando

Qué ejecuta

/portal-setup

Configuración inicial por carpeta + Q&A de alineación → configuración + resumen del proyecto.

/portal-build <spec>

El pipeline completo construir→estilizar→responsive→depurar→adversario→asesor para un bloque.

/portal-theme <goal>

Diseñar o aplicar un tema para todo el portal.

/portal-bulk <change>

Un cambio masivo protegido en muchos bloques/páginas (instantánea → simulación → aplicación atómica).

/portal-audit [filter]

Auditoría de solo lectura de bloques existentes: errores, accesibilidad, responsive, ajuste de diseño.

/portal-improve

Una pasada de mejora acotada: puntuar → arreglar los peores bloques → verificar → barrer → delta demostrable. Seguro de programar cada noche.

/portal-align

Ejecutar el Q&A de alineación por sí solo.

Enrutamiento de modelo y esfuerzo

Cada agente se ejecuta con el modelo y el esfuerzo de razonamiento que se ajustan a su trabajo: preciso donde importa el juicio, barato donde el trabajo es mecánico. Tres capas que se componen:

1 · Valores predeterminados de agente (model:/effort: en frontmatter): para una llamada directa (una edición quirúrgica rápida, o un agente despachado desde un comando):

Nivel

Agentes

Modelo · esfuerzo

🧠 Juicio / datos

data-expert, adversary, advisor

opus · alto

🛠️ Autoría

builder, stylist, debugger, bulk-operator, theme-designer, onboarding

sonnet · medio

⚡ Mecánico

responsive-specialist

haiku · bajo

2 · Alternancia de tier del flujo de trabajo: portal-block-pipeline.js y portal-audit.js aceptan args:{ …, tier } y establecen el modelo/esfuerzo de cada etapa explícitamente:

tier

Para…

Constructores

Compuertas de juicio

fast

iteración barata, borradores desechables, triaje

sonnet/haiku · bajo

sonnet · medio

standard (predeterminado)

una construcción / auditoría normal

sonnet · medio

opus · alto

max

construcción de producción / ejecutiva, auditoría previa al lanzamiento

opus · alto

opus · muy alto

3 · Comandos fijados en sonnet · medio: solo orquestan (pre-vuelo → despacho → síntesis); la calidad vive en los agentes/flujo de trabajo que llaman. /portal-build y /portal-audit infieren el tier a partir de tu redacción.

El servidor MCP nunca selecciona un modelo: solo lo hacen los agentes, comandos y flujos de trabajo que lo impulsan. Re-nivela mediante el frontmatter del agente o la tabla ROUTING de un flujo de trabajo; consulta .claude/README.md.


Incorporación guiada y temática

Por defecto, configure_project sirve un pequeño formulario web de bucle local (http://127.0.0.1:<puerto-aleatorio>) desde el proceso MCP, abre tu navegador con el mejor esfuerzo y devuelve el enlace de inmediato: escribes la URL, la clave API, los interruptores de seguridad de escritura, el alcance de acceso y el control de versiones en el navegador, de modo que la clave API nunca pasa por el modelo. Al guardar, valida en vivo, escribe la configuración 0600 ignorada por git y aplica el cambio en vivo. Recurre a la elicitación del MCP (indicaciones campo por campo) y luego a argumentos cuando no se puede usar un navegador: pasa ui:false, o pasa portal_url + api_key + user_id como argumentos. La temática guiada es el prompt MCP design_intake, que orquesta la herramienta pura synthesize_theme. Consulta El formulario de configuración del navegador.

flowchart TB
    subgraph setup["🔌 configure_project — connect a portal"]
        direction TB
        s1["Portal URL"] --> s2["API key 🔒"] --> s3["User ID"] --> s4{"add GitHub VC?<br/>(optional)"}
        s4 --> s4b{"use Claude for Chrome?<br/>👁️ visual checks"}
        s4b --> s5["✓ live portal login<br/>✓ GitHub token + repo (API)"] --> s6[["writes .zuar-portal/config.json<br/>+ .gitignore"]]
    end
    subgraph intake["🎨 design_intake prompt — theme the portal"]
        direction TB
        d1["brand + website"] --> d2["fetch site 🛡️ SSRF-guarded<br/>→ suggest brand colors"] --> d3["palette · density · radius"]
        d3 --> d4["header + sidebar style"] --> d5{"confirm?"} --> d6[["synthesize_theme →<br/>create_resource (theme)"]]
    end
  • configure_project se niega a sobrescribir una configuración existente, valida con un inicio de sesión real y escribe un ./.zuar-portal/ ignorado por git. También pregunta si usas Claude for Chrome (almacenado como browser.claudeInChrome) para que el pipeline de construcción pueda ver renderizar tus bloques: depuración visual + una compuerta visual final (consulta Ver el portal). El prompt setup_zuar_project y /portal-setup enrutan a él; pasa interactive: false para la ruta directa sin indicaciones. (Reemplaza setup_portal e init_project_config de la v2.)

  • El prompt design_intake obtiene el sitio web de la marca a través de la búsqueda protegida contra SSRF de synthesize_theme para sugerir una paleta, luego recorre densidad/radio/encabezado/barra lateral y, con tu confirmación, crea un recurso theme mediante create_resource. synthesize_theme en sí es puro: devuelve el mapa de tokens y la llamada exacta create_with, y nunca escribe.


Requisitos

  • Un Zuar Portal accesible por HTTPS, con una cuenta que pueda gestionar bloques (se recomienda administrador).

  • Node.js 18+: para Claude Code y cualquier otro cliente MCP. (El .mcpb de un clic de Claude Desktop incluye su propio Node, así que no necesitas nada.)

Obtener tus credenciales del portal

Necesitas tres valores, introducidos una vez durante la instalación.

#

Valor

Dónde

1

Portal URL

La URL de un portal, sin la ruta final, p. ej. https://your-portal.zuarbase.net.

2

Portal API Key

Admin → Auth → API Keys → crea/copia una clave. Hereda los permisos de su usuario (y ese usuario debe poder crear, editar y eliminar bloques).

3

Portal User ID

Admin → Users → tu usuario → copia el UUID que aparece en la URL de la página.

[!IMPORTANT] Mantén privadas la API Key y el User ID. En el bundle de Claude Desktop se declaran como sensibles (enmascaradas, guardadas de forma segura) y no abandonan jamás la máquina donde se ejecuta el servidor.


Instalación — Claude Desktop (un clic)

  1. Descarga zuar-portal-mcp.mcpb de la última versión.

  2. Haz doble clic en el archivo, o bien arrástrelo a la ventana de Claude Desktop. Se abrirá un diálogo de instalación.

  3. Rellena Portal URL, Portal API Key y Portal User ID (y, opcionalmente, los conmutadores para la seguridad de escritura).

  4. Confirma. Las herramientas, los recursos y los prompts quedan disponibles para Claude.

Para actualizarlo más adelante, instala un .mcpb más nuevo sobre el anterior.

Instalación — Claude Code y otros clientes MCP

Este servidor habla MCP por stdio, así que cualquier cliente compatible con MCP puede usarlo. Clónalo, compílalo una vez y registra el punto de entrada de la compilación; para eso necesitas Node ≥ 18 y git.

Regístralo una sola vez para todos los proyectos:

git clone https://github.com/zuarbase/Zuar-Portal-MCP-Public.git ~/zuar-portal-mcp
cd ~/zuar-portal-mcp
npm install
npm run build
claude mcp add zuar-portal --scope user -- node ~/zuar-portal-mcp/dist/index.js

[!IMPORTANT] Deja el clon donde está. claude mcp add registra la ruta absoluta a dist/index.js; si mueves o borras la carpeta, el servidor se romperá con un spawn ENOENT. Elige un destino permanente — ni /tmp ni ~/Downloads.

Para actualizarlo: haz pull y recompila en el lugar. La ruta no cambia, así que no tienes que volver a registar; pero reinicia el cliente, porque la lista de herramientas solo se obtiene durante el handshake.

cd ~/zuar-portal-mcp && git pull && npm install && npm run build

Luego, se en cada carpeta de proyecto del portal conéctalo a ese portal:

mkdir ~/work/acme-portal && cd ~/work/acme-portal
claude
> /portal-setup

/portal-setup te pide tus tres valores, los verifica con un inicio de sesión real y escribe un ./.zuar-portal/config.json ignorado por .gitignore. Cada carpeta puede apuntar a un portal diferente — ver Configuración por proyecto ↓.

En el \.mcp\.json del proyecto (o en claude_desktop_config.json) — apunta args al punto de entrada compilado de tu clon, con una ruta absoluta (aquí ~ no se expande):

{
  "mcpServers": {
    "zuar-portal": {
      "command": "node",
      "args": ["/Users/you/zuar-portal-mcp/dist/index.js"]
    }
  }
}

[!IMPORTANT] Deja env vacío. No pongas PORTAL_URL / PORTAL_API_KEY / PORTAL_USER_ID en tu config del cliente. Las credenciales en el mapa env del cliente deben guardar one portal global que todos los proyectos heredan en silencio — así que una que una encontrada carpeta que crees que apunta a preproducción acaba publicando en producción sin que te des cuenta. En su lugar, deja que /portal-setup credades de escritura por proyecto. Así, cada proyecto lleva una fe de huella, y el servidor rechaza una escritura dirigida a un portal al que esa carpeta no está vinculada. Las variables de entorno siguen funcionando (últiles para la CI o un instalación de un solo portal), pero el archivo de proyecto es la vía que no te puede dar sorpresas.


Configuración por proyecto (varios portales)

Una instalación de MCP puede impulsar un portal diferente — y un repositorio de estado git diferente — en cada carpeta. Al arranaryerver, el servidor resuelve las credenciales por capas, que nadie tenga prioridad:

flowchart LR
    A["1 · Project config<br/><code>./.zuar-portal/config.json</code><br/>(walks up from cwd)"] --> R{{"resolved<br/>credentials"}}
    B["2 · Environment<br/><code>PORTAL_*</code> env vars<br/>(Desktop / MCPB)"] --> R
    C["3 · Bundle config<br/><code>config.json</code> beside bundle"] --> R

La mayoría de las opciones se resuelven por campo, así que un archivo de proyecto puede definir solo vc.dir y heredar el resto. Los valores vacíos se ignoran, de modo que un valdo en blanco en Desktop puede heredar de la herencia de un proyecto.

[!WARNING] Las credenciales del portal son la excepción: el situarlas de un solo desde UNA capa (de la capa) (v4.0.0). Una capa que nombre cualquiera de url / apiKey / userId debe proporcionar todas las tres, o el arranque falla con error explícito. La fusión por campos supuso un riesgo entre portales: un proyecto con url pero sin apiKey tomaba silenciosamente PORTAL_API_KEY del entorno — la dirección de un portal junto con la clave de otro.

El archivo usa un único esquema tanto para el portal como para su repo de control de versiones:

{
  "portal": { "url": "https://team-a.zuarbase.net", "apiKey": "…", "userId": "…" },
  "vc":     { "dir": "/path/to/team-a-state", "push": true,
              "remote_url": "https://github.com/you/team-a-portal-state.git", "token": "…" }
}

Móntalo sin editar el JSON a mano: pide a Claude que ejecute configure_project (ver Incours guidado ↑). get_capabilities muestra el portal/repo que está en vigor bajo su clave config (secretos enmascarados). ./.zuar-portal/ está en .gitignore, así que las credenciales no se gitignore.


Primeros pasos

¿Portal nuevo? Empieza aquí. Desde la carpeta en la que trabajo:

cd ~/work/acme-portal
claude
> /portal-setup

Un solo comando, and conecta la carpeta al portal (escribe las credenciales ignorado por git + una huella de vinculación), per filtra las fuentes de datos, entabla una entrevista sobre el negocio y escribe un resumen del proyecto que leerán los demás. Todo lo que sigue asume que este paso ya está hecho.

A continuación, solo pregunta a Claude:

  1. Comprueba la conexión — "Lista las fuentes de datos de mi portal." → list_resource (datasource).

  2. Mira datos reales — "Muéstrame algunas filas de la fuente de datos Sales." → profile_datasource (estadísticas por columna y filas de ejemplo reales, para que Claude vea los nombres reales de las columnas).

  3. Crea un bloque — "Crea un bloque tarjeta de estadística 'Total Orders' para mostrar el recuento de pedidos de Sales." → lee zportal://guide/*, construye el bloque de la dos-ficha, create_block e informa el UUID.

  4. Itera — "Haz el número de mayor tamaño y que use el color principal del portal." / "Conviértelo en un gráfico de barras de pedidos por estado." → update_block.

[!TIP] En Claude Code, ejecuta /portal-build "a stat card of total orders from Sales" para cruzar todo el pipeline con barreras y compuertas, o utiliza el prompt create_zportal_block para un flujo estructurado de descubrir → construir → crear.


Seguridad de escritura y compuertas herramientas

Cada escritura lleva una etiqueta de dominio de riesgo, con una compuerta independiente:

Dominio

Qué cubre

Por defecto

Activación

content

bloques, diseños, partiales, temas, consultas, fragmentos, traducciones, paneles, etiquetas

activado

(activado siempre que no sea de solo lectura)

data

fuentes de datos, db_modifications, run_db_modification

desactivado

PORTAL_ALLOW_DATA_WRITES=1

admin

usuarios, grupos, permisos, políticas de acceso, claves de API, credenciales, sistema, config, contraseñas

desactivado

PORTAL_ALLOW_ADMIN_WRITES=1

  • PORTAL_READONLY=1 desactiva todas las escrituras — aunque las lecturas y el descubrimiento siguen funcionando.

  • Un escritura bloqueada devuelve un mensaje claro con el flag que debe activarse; no hay ninguna operación que en el portal.

  • run_db_modification — además, require confirm: true en toda llamada.

  • Las eliminaciones y las mutaciones de contraseñas de usuario se marcan como destructivas para los clientes MCP.

  • dry_run: true uniforme (v3.0.0) — todas las compuertas se ejecutan (dominio, estructura, reglas por tipo, referencias, impacto), pero no se escribe nada; la respuesta informa applied: false y qué what 's changed. Una ejecucion seca nunca se salta una compuerta.

Ámbito de herramientas de privilegio mínimo (v2.5.0) — desactiva grupo completo de capacidad con PORTAL_DISABLE_TOOLS=users,config, o activa una lista blanca de solo compilación con PORTAL_ENABLE_TOOLS=blocks,resources,data (la denegación gana).

Actualización desde 2.x — PORTAL_COMPAT_TOOLS=1 (apagado por defecto) registra los nombres de herramientas de v2 eliminadas como aliases deprecated en un grupo compat; cada alias reenvía al mismo handle de v3 con compuertas, por lo que los aliases no agregan ningún privilegio adicional.

Compuertas de integridad (v2.5–2.6, en el servidor, no se puede eludir) — toda escritura de contenido se comprueba con estructura compatible del portal (una página que falda de grid.layouts se reviertea/rechaza) y referencias a badeas; el eliminación ejecuta anális de impacto previo de eliminar y evita la huérfanización de dependientes sin force=true; los borrados de usuarios no permiten eliminar al último administrador; el SQL masivo sin ámbito (destructive verb without a real WHERE — 1=1 doesn't count — plus MERGE/TRUNCATE/DROP/ALTER…DROP/GRANT) needs allow_unfiltered=true, and the check fails closed when the SQL can't be inspected. Run the read-only validate_portal anytime to fix code / find issues. Full manual: docs/16 · Safety & Integrity.

Seguridad para bucles desatendidos (no publicado) — las garantías de que los bucles paralelos/nocturnos de agentes se pueden dejar sin atención:

  • Sin duplicaradores de creación: Un create que falla de modo ambiguo (la red se cayó después de que la solicitud haya quedado registrada) se verifica por nombre y se adopta si de la ya existe: nunca se vuelve a enviar a ciegas. run_db_modification nunca se reintenta automáticamente.

  • Sin actualizaciones perdidas: pasa expected_updated_at (desde tu lectura) a update_resource / update_block / place_blocks y, si alguien modifica algo a mitad de vuelo, responde con un conflicto en lugar de sobrescribir en silencio.

  • Sin objetos residuales: los nombres de los temporales del bucle atmp · <propósito> (o etiquetarlos scratch) y ponlos a soplar con cleanup_scratch — por defecto solo prueba contra y elimina solo candidatos sin referencia ni recientes, con el camino de compuertas, manteniendo el contenido restorable desde el VC.

  • Progreso verificable: score_portal pone el puntaje a cada bloque/página con la indicación 0–100 sobre el issues reproduciblesmente y se calcula un diff contra un offline(base) guardado — la regresión del bucle es un delta por registro, no un anécdota.

  • Admin no se protege a sí mismo: eliminar tu propio acceso a administración requiere allow_self_lockout=true; update_config y change_password exigen confirm (las ediciones de configuración devuelven previous_at_path para revertir con una sola llamada).

estos interruptores en el Desktop se ofrecen en el diálogo de instalación; para otros clientes, configúralos como variables de entorno. Para más: docs/14 · Tool Gating & Guidance.


Resiliencia, observabilidad y endurecimiento

Comportamiento de nivel de producción para un servidor local de un solo usuario — con valores por defecto seguros, sin configuración requerida.

Resiliencia (el cliente HTTP del portal por el que pasa toda herramienta):

Comportamiento

Por defecto

Ajuste con

Tiempo de espera por intento

30 s

PORTAL_TIMEOUT_MS

Reintentos ante fallos transitorios (red, 408/425/429/5xx), retroceso exponencial con jitter, respetando Retry-After

2

PORTAL_MAX_RETRIES, PORTAL_BACKOFF_BASE_MS, PORTAL_BACKOFF_MAX_MS

Interruptor de circuito: falla rápido mientras el upstream esté caído

se abre tras 5 fallos, 15 s de enfriamiento

PORTAL_BREAKER_THRESHOLD, PORTAL_BREAKER_COOLDOWN_MS

Tamaño máximo del cuerpo de la solicitud

5 MB

PORTAL_MAX_BODY_BYTES

Tamaño máximo de entrada de la herramienta (rechazado en el límite de MCP)

2 MB

PORTAL_MAX_INPUT_BYTES

Límite de filas devueltas por execute_query

1000 filas (limit:0 = todas)

limit por llamada

Límite de bytes por página de list_resource (proyecta automáticamente a {id,name} + nota)

60 000 caracteres

PORTAL_LIST_BYTE_CAP (0 desactiva)

Serialización de resultados

JSON compacto

PORTAL_PRETTY_JSON=1 para formato legible

Frecuencia de reverificación de la vinculación

10 min + al recargar la configuración

PORTAL_BINDING_REVERIFY_MS

Caché de lectura (GET; cualquier escritura la invalida; las lecturas críticas de escritura la omiten)

TTL de 5 s

PORTAL_READ_CACHE_MS (0 desactiva)

Seguridad de reintentos: GET se reintenta ante cualquier señal transitoria; las escrituras solo se reintentan ante una contrapresión explícita 429/503 o un fallo de red que demuestre que nunca llegó a conectarse — nunca ante un 502/504 ambiguo, y una creación cuyo error de red pueda haber entregado la solicitud se verifica por nombre y se adopta en lugar de reenviarse (sin duplicados silenciosos).

Observabilidad — cada llamada recibe un id de solicitud, una latencia y un recuento de errores. get_metrics (siempre activo) reporta recuentos por herramienta, tasa de error, latencia, tiempo de actividad y el estado del interruptor — solo metadatos, sin cargas útiles ni secretos. Configura PORTAL_LOG_FORMAT=json para obtener registros estructurados en stderr; PORTAL_AUDIT_LOG agrega JSONL solo con metadatos para cada escritura de contenido/datos/administración.

Enmascaramiento de secretos en la salida. — los campos que contienen secretos (password, secret, token, api_key, …) se enmascaran como [redacted] en las lecturas de recursos, de modo que nunca llegan al contexto del modelo; los secretos también se detectan por forma dentro de cualquier valor o nombre — contraseñas de cadenas de conexión (postgresql://user:[redacted]@host), JWTs, claves privadas PEM, ids de claves AWS — incluidos en los resultados de execute_query / profile_datasource. Las formas genéricas hexadecimales y key=value no se enmascaran deliberadamente (los UUIDs, los git shas y los parámetros SQL son contenido legítimo que viaja de vuelta a las escrituras). Los campos de identificador *_id nunca se enmascaran; las respuestas de crear/actualizar se conservan intactas (para que un secreto recién generado pueda verse una vez). Desactívelo con PORTAL_REDACT_SECRETS=0. El contenido de Portal se devuelve, además, dentro de un envoltorio de datos no confiables, de modo que un nombre de registro envenenado se lea como datos, no como instrucciones.


Solución de problemas

Síntoma

Causa probable / solución

"failed to connect" / spawn ENOENT

El cliente no pudo lanzar el comando. O bien (a) el clon se movió o se eliminó — claude mcp add guardó una ruta absoluta a dist/index.js; vuelve a comprobarlo con claude mcp list; (b) lo registraste antes de ejecutar npm run build, así que dist/index.js no existe — compila y luego reinicia el cliente; o (c) node no está en el PATH que ve tu cliente (común con nvm + Claude Desktop, que no carga tu perfil de shell — usa el .mcpb ahí, incluye su propio runtime).

Una guía antigua dice que ejecutes npx -y zuar-portal-mcp-server

Ese paquete no está en npm — el comando no puede funcionar y falla con ENOENT. Instala desde un clon: Instalación — Claude Code ↓.

Las lecturas funcionan, pero cada escritura se rechaza como unbound

Esta carpeta no está vinculada a un portal. Ejecuta /portal-setup (o configure_project) en ella. El vínculo es lo que evita que el bloque de un proyecto se publique en el portal de otro, así que es deliberado — ver Configuración por proyecto.

"Missing portal credentials: …"

Uno de PORTAL_URL / PORTAL_API_KEY / PORTAL_USER_ID está vacío. Vuelve a introducirlo.

"…must supply all three of url/apiKey/userId"

Una capa de configuración nombra algunas credenciales pero no todas. Eso se rechaza a propósito — un url sin apiKey solía tomar prestada la clave de tu entorno en silencio, emparejando la dirección de un portal con la clave de otro. Proporciona las tres en un solo lugar.

"Portal login failed: HTTP 401/403"

Clave de API o ID de usuario incorrectos, o el usuario no tiene permiso. Regenera la clave; confirma que el usuario puede gestionar bloques.

list_resource (query) dice que el endpoint no está disponible

Tu portal es anterior a la API de consultas guardadas (1.18+). Usa resource: "datasource" — es lo esperado, no un error.

Las herramientas no aparecen en Claude

Reinicia el cliente — la lista de herramientas se obtiene una vez en el handshake, así que un servidor recién añadido (o una versión nueva) no aparecerá en una sesión en ejecución. Para el .mcpb, reinstálalo.

Actualizaste pero las nuevas herramientas/reglas no están ahí

Misma causa: el cliente sigue ejecutando el proceso antiguo. Reinícialo.

Falta un nombre de herramienta v2 (list_blocks, setup_portal, …)

v3.0.0 lo eliminó/renombró — ver CHANGELOG.md para el reemplazo, o establece PORTAL_COMPAT_TOOLS=1 para alias de reenvío obsoletos.

Quieres ver qué está haciendo

Establece PORTAL_DEBUG=1 (o PORTAL_LOG_FORMAT=json). Los registros van solo a stderr.

"circuit breaker is open"

El upstream falló repetidamente; se recupera automáticamente tras un breve enfriamiento. get_metrics muestra el estado del breaker.

Un secreto almacenado devuelve [redacted]

La redacción de lectura está activada. Establece PORTAL_REDACT_SECRETS=0 para esa sesión.

Más: docs/12 · Solución de problemas.


Seguridad

  • Las credenciales nunca se registran. La salida de depuración (controlada por PORTAL_DEBUG=1) va solo a stderr, así que nunca corrompe el flujo stdio de MCP.

  • La clave de API y el ID de usuario se declaran sensibles en el manifiesto del paquete.

  • El servidor solo habla con la URL del portal que configures; la URL base se valida como un origen http(s) bien formado al inicio. La recuperación web de synthesize_theme (impulsada por el prompt design_intake) está protegida contra SSRF.

  • create_block / update_block están restringidos a type: "html" y rechazan otros tipos antes de cualquier llamada al portal.

  • Los campos con secretos se redactan en las lecturas; las entradas de herramientas y los cuerpos de solicitud tienen límite de tamaño.

Ver SECURITY.md para la postura completa: la matriz de acceso a datos por grupo de herramientas, el manejo de credenciales, la salida de red y la retención de datos.

Licencia

MIT.

Available Tools

40 tools
bind_block_queryBind a block to a datasource/queryA

Give an existing block its data binding so currentBlock.queryResults[0] is populated. Pass an existing query_id, OR a datasource_id (a SELECT * query is auto-created against it and linked). Sets the block's ui_queries while preserving its html/css/name. The bound query must have a datasource (auto-created ones do) or the portal rejects it.

NameRequiredDescriptionDefault
sqlNoOptional raw SQL for the auto-created query (use alias `datasource` as the table). Only with datasource_id; default is SELECT *.
dry_runNoPreview the binding without writing (with datasource_id, the SELECT * query is NOT created either).
block_idYesBlock UUID to bind.
query_idNoExisting saved query UUID. Mutually exclusive with datasource_id.
page_sizeNoRows fetched into queryResults. Omit for the default null = ALL rows (preferred — the block sees the full dataset). Set a positive number only to cap intentionally (e.g. a small preview); a low cap truncates the data the block sees.
datasource_idNoDatasource UUID — auto-creates a SELECT * query against it. Mutually exclusive with query_id.

TDQS

A4.6/5.0
Behavior4/5

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

Annotations indicate readOnlyHint=false, destructiveHint=false, and idempotentHint=false, but the description adds valuable behavioral context: it explains that binding populates queryResults, preserves html/css/name, and that auto-created queries are linked. It also discloses the rejection condition (missing datasource) and the dry_run behavior. This goes beyond the annotations, though it doesn't detail side effects like whether existing ui_queries are overwritten or how the portal handles failures.

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?

The description is concise and well-structured: it opens with the core purpose, then explains the two binding modes, and ends with a critical constraint. Every sentence adds information without redundancy. The parameter details are left to the schema, keeping the description focused.

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?

Given the tool's complexity (6 parameters, two mutually exclusive modes, auto-creation behavior, and a rejection condition), the description covers the essential usage scenarios. It doesn't explicitly state what happens to existing ui_queries or how the response looks, but since there's no output schema and the tool is a mutation, the description provides enough for an agent to call it correctly. The missing details are minor and could be inferred from the schema.

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 description coverage is 100%, so the schema already documents all parameters. The description adds value by clarifying the relationship between query_id and datasource_id (mutually exclusive), explaining the default behavior of page_size (null = ALL rows, preferred) and the implications of setting a cap, and noting that sql is only used with datasource_id. This enriches the schema's basic descriptions.

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?

The description clearly states the tool's purpose: 'Give an existing block its data binding so currentBlock.queryResults[0] is populated.' It specifies the resource (block) and the action (bind to a datasource/query), and distinguishes it from siblings like create_block and update_block by focusing on data binding rather than block creation or general updates.

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?

The description provides explicit usage guidance: it explains the two mutually exclusive options (query_id vs datasource_id), notes that datasource_id auto-creates a SELECT * query, and warns that the bound query must have a datasource or the portal rejects it. It also mentions the dry_run option for previewing without writing, which helps agents decide when to use it.

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

change_passwordChange the current user's passwordA
Destructive

Change the authenticated user's password. Requires admin writes enabled (PORTAL_ALLOW_ADMIN_WRITES=1) and confirm=true — this rotates the credential the current session signs in with. Passwords are never logged or echoed back.

NameRequiredDescriptionDefault
confirmNoMust be true — this rotates YOUR OWN login credential; the old password stops working immediately.
new_passwordYesNew password.
old_passwordYesCurrent password.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true and readOnlyHint=false, and the description adds valuable behavioral context: it rotates the current session's credential, requires admin writes, and notes that passwords are never logged or echoed. This goes well beyond the structured annotations and warns the agent about irreversible side effects.

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?

The description is two sentences with no filler. The core action and prerequisites are front-loaded, and the security note about logging is a meaningful addition that earns its place.

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?

Given the full parameter schema, destructive/read-only annotations, and the description's coverage of prerequisites, side effects, and security behavior, an agent has everything needed to invoke this tool correctly. No output schema exists, but the description does not need to explain return values for this mutation.

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%, so the schema already documents old_password, new_password, and confirm. The description reiterates that confirm=true is required and explains the credential rotation, but it does not add new parameter-level details beyond what the schema's confirm description already states.

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?

The description states a specific verb and resource: 'Change the authenticated user's password.' This clearly distinguishes it from sibling tools like update_config or set_user_access, which operate on different resources. The title reinforces the same precise scope.

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?

The description gives explicit prerequisites: admin writes must be enabled (PORTAL_ALLOW_ADMIN_WRITES=1) and confirm must be true. It does not name alternatives, but no sibling tool appears to be a password-change alternative, so the context is sufficient for an agent to know when to invoke it.

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

check_connectionConfirm the portal connectionA
Read-only

START HERE — confirm in ONE authenticated round-trip which Zuar Portal this folder is on, its version, who you're signed in as, what you may write, and whether browser assist is on. Proves the credentials actually work, and on failure reports the reason and the fix. Returns a few short fields rather than a JSON wall — call get_capabilities only if you then need the full tool/group, VC and audit posture.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the description doesn't need to restate safety. It adds valuable behavioral context: it proves credentials work, reports failure reason and fix, and returns a few short fields rather than a JSON wall. This goes beyond the annotations by describing the failure reporting and response format, which is useful for an agent.

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?

The description is concise and front-loaded with the 'START HERE' directive, immediately establishing the tool's role. Every sentence adds value: the first states the purpose and scope, the second explains the credential proof and failure handling, and the third clarifies the response format and when to use an alternative. No wasted words.

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 zero-parameter tool with readOnly and openWorld annotations, the description is complete. It covers what the tool does, what it returns, when to use it, and when to use an alternative. The absence of an output schema is mitigated by the description's clear statement of the returned fields. An agent has everything needed to call it correctly.

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 has zero parameters, so the schema provides no parameter documentation. The description compensates by explaining what the tool returns (portal, version, user, write permissions, browser assist status) and how it behaves (single round-trip, failure reporting). Since there are no parameters to document, the description effectively covers the tool's semantics.

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?

The description clearly states the tool's purpose: confirm in one authenticated round-trip which Zuar Portal this folder is on, its version, who you're signed in as, what you may write, and whether browser assist is on. It uses a specific verb ('confirm') and resource ('portal connection'), and distinguishes itself from get_capabilities by noting it returns a few short fields rather than a full JSON wall.

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?

The description explicitly says 'START HERE' and instructs to call get_capabilities only if the full tool/group, VC and audit posture is needed. This provides clear when-to-use guidance and names the alternative tool, making it easy for an agent to decide between check_connection and get_capabilities.

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

cleanup_scratchSweep scratch leftovers (loop hygiene)A
DestructiveIdempotent

Find records that scratch conventions mark as disposable — a name starting 'TMP ·', a 'scratch'/'tmp' tag, or '(delete me)' in the name; optionally '(diagnostic)' records and unnamed ones. DRY-RUN BY DEFAULT: reports every match, why it matched, and what (if anything) references it. confirm=true deletes only the safe candidates — unreferenced, not recently touched — through the same gated delete path as delete_resource. Content deletes are VC-recorded (restorable); db_modification deletes are NOT restorable and only ever match the explicit TMP/scratch markers.

NameRequiredDescriptionDefault
kindsNoKinds to sweep (default: query, block, db_modification).
confirmNotrue = delete the safe candidates. Omit for the dry-run report.
max_deleteNoCap deletions per run (default 50); the remainder is reported.
include_unnamedNoAlso flag null/empty-named records — content kinds only, never db_modifications. Default false.
older_than_minutesNoOnly records untouched this long are candidates — a running loop may still need newer ones (default 60; 0 disables).
include_diagnosticsNoAlso flag '(diagnostic)'-suffixed records (e.g. 'SYS · Block Inspect (diagnostic)'). Default false.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and readOnlyHint=false, so the description doesn't need to restate that this can delete. However, it adds valuable context beyond annotations: the dry-run default, the distinction between VC-recorded (restorable) content deletes and non-restorable db_modification deletes, and the safety criteria (unreferenced, not recently touched). This is rich behavioral disclosure that goes beyond what annotations provide. The only minor gap is not explicitly stating that the tool is idempotent (though annotations declare idempotentHint=true), but the description's detail on safety and restorability is strong.

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?

The description is dense but well-structured. It front-loads the matching criteria and the dry-run default, then explains the deletion behavior and restorability. Every sentence adds meaningful information — no filler. The use of em-dashes and parentheticals packs a lot of detail without becoming unwieldy. It's appropriately sized for a tool with 6 parameters and complex safety semantics.

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 tool with 6 parameters, no output schema, and destructive potential, the description is remarkably complete. It covers what matches, what gets deleted, safety criteria, restorability, and defaults. The only thing an agent might want is an example output format for the dry-run report, but the description already explains what the report contains (every match, why it matched, what references it). Given the complexity and the annotations covering safety, this is complete enough for correct invocation.

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 description coverage is 100%, so the schema already documents all 6 parameters. The description adds value by explaining the default behavior (kinds default to query/block/db_modification, max_delete default 50, older_than_minutes default 60) and the safety semantics (older_than_minutes protects running loops, include_unnamed never applies to db_modifications). This goes beyond the schema's basic descriptions, providing operational context that helps an agent choose correct parameter values.

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?

The description clearly states the tool's purpose: finding and optionally deleting records that scratch conventions mark as disposable. It specifies the matching criteria (name starting 'TMP ·', 'scratch'/'tmp' tag, '(delete me)' in name) and distinguishes it from the general delete_resource sibling by emphasizing the dry-run default and the gated delete path. This is a specific verb+resource with clear scope.

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?

The description explicitly explains when to use this tool (for cleaning up scratch leftovers) and contrasts it with delete_resource, noting that deletions go through the same gated path. It also explains the dry-run default and the confirm=true flag for actual deletion, giving clear guidance on when to use the tool versus alternatives. The mention of 'loop hygiene' in the title further clarifies the intended use case.

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

configure_projectConfigure this project's portal connectionA

Connect THIS folder to a Zuar Portal — one install can serve many portals, each folder gets its own ./.zuar-portal/config.json. By default this opens a tiny local setup page (http://127.0.0.1:, single-use token) served by this MCP process, best-effort opening your browser and returning the link immediately (non-blocking): you type the URL, API key, write-safety toggles, access scope, and version-control settings IN THE BROWSER, so the API key never passes through the model. On Save it validates the portal with a live login, writes the config + a .gitignore (0600, secrets never committed), then PINS the folder to the portal's live identity (later writes to a DIFFERENT portal are refused) — all applied live, no restart; the success page points you at design_intake to scaffold this project's design.md + CLAUDE.md. The write-safety toggles are set ONLY via this human form (no tool argument sets them), and WIDENING data/admin writes additionally needs the env opt-in PORTAL_ALLOW_OPERATOR_TOGGLES, so an agent can never widen its own permissions. Falls back to MCP elicitation, then headless arguments, when a browser can't be used: pass ui:false, or pass portal_url + api_key + user_id as arguments — that path also scaffolds a project design.md every block inherits and a managed CLAUDE.md block. Refuses to overwrite an existing config via the args path unless overwrite=true; the browser form prefills current values and Save is your consent. Secrets are stored locally and never echoed.

NameRequiredDescriptionDefault
uiNotrue/omit = open the local setup page (default); false = skip it and use elicitation / headless args.
vc_dirNoLocal git repo path to mirror content writes into.
api_keyNoPortal API key (Admin → Auth → API Keys). Skips the prompt.
densityNoLayout density for generated blocks (default comfortable). Skips the prompt.
user_idNoYour user UUID (Admin → Users; copy from the URL). Skips the prompt.
vc_pushNoPush after each commit (default true when a remote is set).
scaffoldNoWrite the project design.md and the managed CLAUDE.md block (default true). false = write only the config.
validateNoValidate portal creds with a live login (default true).
vc_tokenNoGitHub PAT for HTTPS push (stored locally, never logged).
overwriteNoOverwrite an existing project config (default false).
vc_remoteNoGit remote name (default origin).
portal_urlNoBase portal URL, e.g. https://your-portal.zuarbase.net (skips the prompt).
theme_modeNoWhich theme modes blocks must support (default light). Skips the prompt.
brand_colorNoBrand accent color (any CSS color, e.g. #0b7285). Seeds this project's design.md. Skips the prompt.
interactiveNotrue = require interactive prompts (fails if the client can't elicit); false = headless, arguments only; omit = auto (prompt when supported and fields are missing).
vc_usernameNoHTTPS username for the token (default x-access-token).
open_browserNoWhen the setup page opens, best-effort open the form in your browser (default true); false just returns the URL.
portal_labelNoA name for this portal, e.g. 'Acme Production'. Used in the binding warnings and refusals, so a wrong-portal mistake reads as a name rather than a hostname. Skips the prompt.
setup_githubNoForce GitHub version control on/off instead of asking.
vc_remote_urlNoGitHub repo URL, e.g. https://github.com/you/portal-state.git
validate_githubNoValidate the GitHub token/repo via the API (default true).
claude_in_chromeNoRecord whether the Claude for Chrome extension is available, so agents may visually verify blocks (screenshot the render, read the console) instead of only reviewing code. Skips the prompt.

TDQS

A4.3/5.0
Behavior5/5

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

Discloses key side effects: writes config, pins to portal identity, refuses overwrite unless overwrite=true, writes to version control, stores secrets locally and never echoes them. Also explains the security restriction that write-safety toggles are only available via browser, preventing agents from widening permissions. This is exceptionally transparent 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?

The description is long but information-dense. It front-loads the core purpose and then explains the flow. Some redundancy exists (e.g., repeated mention of browser fallback), but overall each sentence contributes to understanding. Could be slightly tightened, but acceptable for a complex tool.

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?

Given the tool has 22 parameters, no output schema, and complex side effects (browser interaction, security constraints, version control, fallback behaviors), the description is remarkably complete. It covers all major behaviors, prerequisites, security notes, and interaction flows, leaving the agent well-informed.

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%, but the description adds meaningful context: explains ui default, that api_key skips the prompt, density default, and how the browser path differs from args. It doesn't enumerate every parameter but gives enough to understand their roles, especially the security implications of the ui argument.

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 clearly states the tool's purpose: 'Connect THIS portal to a project folder.' It specifies the verb 'connect/configure' and resource 'portal/project'. It distinguishes itself from sibling tools like update_config by focusing on initial configuration and browser-based setup, but doesn't explicitly differentiate from all siblings.

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 guidance on when to use the browser UI vs headless mode, explains fallback behavior, and mentions the flow after configuration (points to design_intake). It doesn't explicitly mention alternatives like update_config for later changes, but the primary usage context is well covered.

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

create_blockCreate an HTML blockA

Create a new HTML block. Accepts the full block payload (name, css, json_data, ui_queries, tags, access). Type is always html. Read the zportal://guide/* resources first to produce a correct two-field block. Equivalent to create_resource resource="block" with a typed schema; the authoring rules, structural and referential gates run either way. dry_run:true previews.

NameRequiredDescriptionDefault
cssNoBlock CSS. Array form per the portal API; a raw CSS string is also accepted.
dataNoLegacy query-config object. Ignored by current portal versions — bind data via `ui_queries` instead. Kept only for backward compatibility.
nameYesDisplay name of the block.
tagsNoTag names to attach.
typeNoBlock type. This server only handles HTML blocks, so it must be "html".html
accessNoAccess control, e.g. { "groups": ["group-name"] }.
dry_runNoRun every gate and report the would-be write without creating.
css_fileNoPath to a file holding the block's CSS; the server reads it into `css`. Same byte-exact guarantee and same root containment as html_file. Mutually exclusive with `css`.
html_fileNoPath to a file holding the block's HTML+JS; the server reads it into json_data.html. PREFER THIS over inlining large content: the bytes are read off disk byte-exact, so nothing is retyped and characters like em dashes or box-drawing cannot silently normalize. Mutually exclusive with json_data.html. Must resolve under the CWD, the VC dir, or a PORTAL_FILE_ROOTS entry.
json_dataNoWidget/extra config object.
ui_queriesNoQuery/datasource binding (this is how a block gets data — the portal has no `data` field). Array of { enabled, page_size, query_id, filter_strategy }, e.g. [{ "enabled": true, "page_size": 50, "query_id": "<query-uuid>", "filter_strategy": { "type": "blacklist", "value": [] } }]. The query_id must reference a saved query that already has a datasource attached. On update_block, the existing ui_queries is preserved automatically unless you pass a new value.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations indicate readOnlyHint=false, openWorldHint=true, idempotentHint=false, and destructiveHint=false, so the create operation is clearly not read-only. The description adds important behavioral nuance: it warns that the legacy 'data' field is ignored by current portal versions, explains that ui_queries is how data binding works and that update_block preserves existing ui_queries, and clarifies that dry_run only reports without creating. It doesn't cover all failure modes or side effects, but given the annotations already flag non-read-only and non-idempotent, the added context is strong and not contradictory.

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?

The main description is dense and front-loaded with the action, type constraint, and guide reference. However, it is long and packs multiple instructions (equivalence to create_resource, structural gates, dry_run) into a paragraph, and parameter-level guidance is spread across the schema. The information is valuable, but the main description could be more scannable. Still, every sentence earns its place.

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 an 11-parameter tool with 100% schema coverage, no output schema, and nested objects, the description covers prerequisites (reading guides), equivalent alternatives, parameter semantics with examples, and caveats about deprecated fields. The agent has enough to call it correctly without external guesswork. The inclusion of update_block behavior adds forward-looking completeness.

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 100%, so the baseline is 3, but the description adds substantial meaning beyond field names: it explains the legacy nature of 'data' (ignored, kept for backward compat), provides a practical example for ui_queries with a full JSON object, explains the mutual exclusivity and byte-exact reading of css_file and html_file, and notes root containment. This goes well beyond the schema's terse descriptions.

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?

The description states a clear verb and resource ('Create a new HTML block'), explicitly notes the type is always html, and distinguishes it from the generic create_resource while also mentioning the typed alias. It names the related sibling update_block for updates, helping an agent differentiate create from modify behavior.

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?

The description explicitly directs the agent to read zportal://guide/* resources first for correct authoring, mentions dry_run for previews, and clarifies that this is equivalent to create_resource with a typed schema, and that structural and referential gates run either way. It also recommends preferring html_file for large content and notes ui_queries is the proper binding mechanism, providing clear selection and usage guidance.

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

create_resourceCreate a resource recordA

Create a record. body carries the resource's fields (see describe_resource). Writes are gated by risk domain: content is on by default; data (datasources/db_modifications) needs PORTAL_ALLOW_DATA_WRITES; admin (users/groups/etc.) needs PORTAL_ALLOW_ADMIN_WRITES.

NameRequiredDescriptionDefault
bodyYesField values for the new record. Unknown fields are dropped.
dry_runNoRun every gate (domain, structure, per-kind rules, references) and report the would-be write without creating.
resourceYesResource type. Call describe_resource for fields and supported verbs.

TDQS

A4.2/5.0
Behavior4/5

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

The annotations already indicate readOnlyHint=false and destructiveHint=false, but the description adds crucial behavioral context: writes are gated by risk domain, and there is a dry_run parameter to test without creating. This enriches the agent's understanding of the tool's behavior beyond what annotations convey. However, it does not explicitly mention idempotency (which the annotations say is false) or what happens on validation failure, but the dry_run mention partially covers the validation aspect.

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?

The description is two sentences, both packed with essential information. It front-loads the core action and then immediately gives the most critical usage constraint (write gates). No filler words. Perfectly sized.

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?

Given the tool's complexity (three params, one with enum, nested body, write gating), the description covers the key aspects: what it does, how to use it (dry_run), and when it's allowed. It lacks explicit return format, but there is no output schema, so the description should ideally mention what the response contains. However, the description's mention of 'report the would-be write' for dry_run gives some hint. It also doesn't list which resources are admin vs data, but that's covered by the environment variables. Overall, nearly complete.

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?

The schema provides descriptions for all three parameters (body, dry_run, resource), with resource having an enum and clear description. The description adds value by explaining that `body` carries fields and that dry_run runs all gates, but largely repeats what the schema says. Since schema coverage is 100%, the description doesn't need to add much, but it does provide a little extra context about the write gates.

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 clearly states the verb ('Create') and the resource ('record'), and mentions that `body` carries the resource's fields. It distinguishes from siblings like create_block and update_resource by being a generic create. However, it does not explicitly differentiate from create_block, which could be a specific case of create_resource.

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?

The description explicitly states the gating conditions by risk domain: content writes are on by default, while data and admin writes require specific environment variables (PORTAL_ALLOW_DATA_WRITES, PORTAL_ALLOW_ADMIN_WRITES). This tells the agent when it can and cannot use the tool, and implies that for admin/data resources it may need to check permissions first. It also references describe_resource for details, which is helpful.

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

delete_resourceDelete a resource recordA
DestructiveIdempotent

Delete a record by id (or name, for tags). Requires confirm:true. Same write gating as create_resource — the record's risk domain must be enabled. Refuses if other records depend on the target (pass force=true to override) and refuses to remove the last admin / your own account. Content records can be reverted with restore_resource when version control is on.

NameRequiredDescriptionDefault
idYesRecord id to delete.
forceNoDelete even if other records depend on it (leaves those references dangling). Default false.
confirmYesMust be true to actually delete — guards against accidental loss.
dry_runNoReport the delete's impact (dependents) without deleting. get_references gives the same view.
resourceYesResource type. Call describe_resource for fields and supported verbs.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and readOnlyHint=false, so the mutation is known. The description goes beyond by detailing refusal conditions (dependent records, last admin, own account) and the force override effect. It also mentions the restore capability, adding useful context. However, it does not explain the error format or what happens on successful delete (e.g., return value), but given annotations, this is adequate.

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?

The description is compact, two sentences, with key usage conditions front-loaded. It includes important exclusions and alternatives without fluff. Slight deduction for being dense but not overly long; every sentence earns its place.

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?

Given the complexity (5 params, enums) and the absence of an output schema, the description covers the critical usage semantics: confirmation, force, dry_run (via get_references), and resource type. It mentions describe_resource for fields, which helps. It lacks details on return values, but that's not required if no output schema. Overall, it is fairly complete for a destructive 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 each parameter has a description in the schema. The description adds minimal extra: for id, it mentions 'or name, for tags' which is not in the schema. Other parameters are already well documented. Baseline 3 is appropriate as the schema carries most of the burden.

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?

The description clearly states the action: 'Delete a record by id (or name, for tags)' with the resource type parameter. It distinguishes from siblings like restore_resource and get_references by mentioning them. The verb 'delete' is specific and the resource scope is explicit.

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?

The description provides explicit conditions for use: requires confirm:true, same write gating as create_resource, and names alternatives (restore_resource for content records, get_references for viewing dependents). It also clarifies when force=true is appropriate and what it does. This is thorough routing guidance.

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

describe_resourceDescribe a portal resourceA
Read-only

Show a resource's path, write fields, required-to-create fields, supported verbs, and risk domain. Omit resource to list every resource this server manages. Call this before create_resource/update_resource so the body matches the portal schema.

NameRequiredDescriptionDefault
resourceNoResource type. Call describe_resource for fields and supported verbs.

TDQS

A4.8/5.0
Behavior4/5

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

With readOnlyHint=true already provided, the description adds context about optional parameter behavior (omitting resource lists all resources) and the nature of the returned data (schema fields, verbs, risk domain). While it doesn't detail error handling, it enriches the behavioral understanding beyond the annotation.

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?

The description is concise, consisting of two sentences. The first sentence states the primary function, and the second provides an alternative usage and a recommendation. It is well-structured, front-loaded, and contains no fluff.

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?

Given the simplicity of the tool and the absence of an output schema, the description is complete. It covers the main purpose, the optional parameter behavior, and provides a clear usage context. It does not leave significant gaps for an agent to infer.

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?

The tool description adds crucial meaning to the 'resource' parameter by explaining that omitting it lists all resources, which is not mentioned in the schema description. This clarifies the optionality and the effect of not providing the parameter, making the tool's behavior fully understandable.

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?

The description clearly states the tool's function with a specific verb ('Show') and enumerates the information it provides (path, write fields, required-to-create fields, supported verbs, risk domain). It also distinguishes itself by naming a secondary mode (listing all resources) and explicitly positioning it as a precursor to create/update operations, setting it apart from sibling tools like get_resource or create_resource.

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?

The description gives explicit usage guidance: 'Call this before create_resource/update_resource' and notes the behavior when omitting the resource parameter. This clearly tells the agent when to use this tool versus alternatives, providing both a typical workflow and an alternative use case.

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

execute_queryExecute a saved queryA
Read-only

Run a saved query by id and return its results. Pass params as a { name: value } map for parameterized queries. Rows RETURNED are capped at 1,000 by default (a SELECT * on a big table otherwise blows the context budget); the response notes when it truncated. Pass limit for a different cap, or limit:0 for ALL rows (know your table size first). Read-only.

NameRequiredDescriptionDefault
limitNoMax rows to return (default 1000, truncation is noted). 0 = unlimited — all rows.
paramsNoQuery parameters as a { name: value } map.
query_idYesSaved query UUID.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already include readOnlyHint=true, and the description reinforces it. It adds genuinely useful behavioral context about a default 1,000-row cap, truncation notification, and the risk of unlimited queries. This goes beyond generic read-only labeling and explains important edge behavior.

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?

The description is efficient and well-structured: first the core action, then query parameters, then the critical row-limit behavior and caveat. Every sentence adds operational knowledge and the read-only note is prudently repeated despite the annotation.

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 3-parameter read-only query executor with no output schema, the description covers what an agent needs to invoke it correctly: the identifier, parameters, limit behavior, truncation behavior, and safety profile. It does not describe the exact response structure, but that is minimized by the absence of an output schema and the simplicity of the resource.

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 input schema already documents all 3 parameters with rich descriptions, so the baseline is 3. The description adds meaningful usage details above the schema: the default limit of 1,000, the effect of limit=0, and the shape of params as a name/value map. This justifies a 4.

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 the exact action ('Run a saved query by id'), the resource type (saved query), and the outcome (return its results). Distinguished from sibling tools like run_db_modification and get_resource by emphasizing saved, read-only query execution.

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 practical usage guidance: how to pass query parameters, the default row cap, why it exists, how to override it, and the warning about limit:0. It does not explicitly name alternatives or state when not to use this tool, but the context suggests this is the canonical read query executor.

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

find_resourceFind resources by nameA
Read-only

Search records across resource kinds by name — "find the query named X" without listing whole collections client-side. Case-insensitive substring match on name/title, plus exact-id match. Defaults to every non-admin kind (block, layout, partial, theme, query, snippet, translation, dashboard, tag, datasource, db_modification); pass kinds to narrow or to include admin kinds. Optional tag filters to records carrying that tag.

NameRequiredDescriptionDefault
tagNoOnly records carrying this tag.
kindsNoResource kinds to search (default: all non-admin kinds).
limitNoMax results (default 50, max 500).
queryYesName substring (case-insensitive) or an exact record id.
offsetNoResults to skip (pagination).

Output Schema

NameRequiredDescription
queryYes
errorsYes
offsetYes
resultsYes
returnedYes
truncatedYes
total_matchesYes
kinds_searchedYes

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the description correctly implies no side effects. It adds behavioral details beyond the annotation: case-insensitive substring matching, exact-id support, default non-admin kinds, and the effect of `kinds` to include admin kinds. These are useful runtime behaviors not captured by structured metadata.

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?

The description is concise and front-loaded with the core purpose, then packs matching behavior, defaults, and filtering into a logically structured sentence. It avoids redundancy with schema descriptions and uses compact phrasing. Slightly dense but not verbose; every sentence earns its place.

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?

Given the tool's complexity (multiple kinds, filters, pagination via offset/limit), the description covers key usage aspects: matching semantics, defaults, and filtering. The output schema exists, so return values don't need explanation. It lacks explicit mention of pagination behavior, but that is documented in the schema (offset/limit parameters). Satisfactory for a search tool.

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 has 100% description coverage, so the baseline is 3. The description adds value by explaining the default behavior of `kinds` (all non-admin kinds) and how to include admin kinds, which is not explicit in the schema. It also clarifies that `query` can be a substring or exact id. This enriches parameter meaning beyond the raw schema definitions.

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?

The description clearly states the tool searches records across resource kinds by name/title, with a specific verb ('Search records') and resource scope ('across resource kinds'). It distinguishes from siblings like get_resource (which fetches a specific resource) and list_resource (which lists whole collections) by explicitly mentioning the search capability and avoiding full client-side listing.

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 context on when to use it: for finding records by name without listing whole collections, which implies it's preferred over list_resource for name lookups. It also explains defaults and how to narrow with `kinds` and `tag`, but does not explicitly state when *not* to use it (e.g., when you need exact resource retrieval via get_resource). The guidance is implicit rather than explicit exclusions.

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

get_capabilitiesServer capabilities, posture & active configA
Read-only

Report what this server can currently do AND which portal it's pointed at: enabled/disabled tool groups and tools, the write-safety posture (read-only / data / admin), the resolved project config (portal URL + user, config file path), version-control status, browser-assist flag, and whether audit logging is on. THE orientation call — run it before acting; it stays available even when other tool groups are gated off. All secrets are redacted.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already provide readOnlyHint=true, which matches the described posture reporting. The description adds behavioral traits beyond that: redacting secrets, remaining available when other groups are gated, and reporting write-safety posture. It doesn't contradict annotations. Slight deduction because the tool itself is a read operation, but the additional value is significant.

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?

The description is dense but efficient, listing a lot of content in a single flowing sentence, then two short punchy sentences for the 'run it before acting' and redaction hints. Every clause adds value; front-loaded with what it does. No filler.

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?

Given zero params and a rich natural-language spec of the response contents (portal URL, user, config file, vc status, browser-assist, audit log), the description is complete. No output schema exists, so the description compensates by itemizing the report's contents. Nothing omitted that an agent needs to call it correctly.

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?

With 0 parameters and 100% schema coverage, the baseline is 4. The description doesn't add parameter details (none exist), but it enriches the purpose of the no-params call by listing what the response will contain, which helps the agent anticipate output. No loss.

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?

Description states precisely what the tool reports: enabled tool groups/tools, posture, config, vc status, browser-assist flag, audit logging. Identifies itself as 'THE orientation call' and enumerates distinct content areas, clearly distinguishing it from siblings like get_config, get_version, or check_connection.

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?

Explicitly instructs 'run it before acting' and notes it 'stays available even when other tool groups are gated off.' This provides clear when-to-use guidance and implies it should be the first call. No exclusion needed since no alternative tool fulfills this orientation role, and the description effectively differentiates it.

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

get_configGet portal configA
Read-only

Fetch the portal's configuration document.

NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, covering the safety profile and external variability. The description adds no additional behavioral context beyond restating the fetch operation, but it does not contradict the annotations and the annotations carry the burden well.

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 with no filler. It states the action and the target resource economically, which is ideal for such a simple 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 parameterless read-only tool, the description is largely sufficient. With no output schema, it could briefly mention the return format or that it returns the full configuration document, but the phrase 'configuration document' already implies the core outcome.

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 has zero parameters, so the baseline is 4. The description does not need to explain parameter behavior because there are none to document.

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?

The description states a specific verb ('Fetch') and a precise resource ('the portal's configuration document'), clearly distinguishing it from siblings like update_config and reload_config. Even without reading the schema, an agent knows exactly what this tool retrieves.

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 implies the tool is for retrieving configuration, which is clear context. However, it does not explicitly mention that users should prefer this over get_capabilities or describe when not to use it. For a simple getter this is acceptable but not explicit.

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

get_metricsTool-call metricsA
Read-only

Report in-memory observability metrics for THIS server process: per-tool call count, error count/rate, and latency (avg/max/last ms), plus rolled-up totals, uptime, and the upstream circuit-breaker state. Metadata only — no payloads or secrets. Resets when the process restarts. Use it to spot a failing tool or a degraded portal upstream.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the description doesn't need to restate that. It adds valuable context: metrics are in-memory and reset on process restart, and it explicitly states no payloads or secrets are included. This goes beyond the annotations by disclosing the ephemeral nature of the data and the scope of what's reported.

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?

The description is concise and front-loaded with the core purpose. It lists the metrics in a compact list, adds the metadata-only caveat, notes the reset behavior, and ends with a usage recommendation. Every sentence adds value with no redundancy.

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 parameterless, read-only tool with no output schema, the description is complete. It covers what metrics are reported, the scope (this server process), the ephemeral nature, and the intended use case. An agent has everything needed to decide when to call it and what to expect.

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 has zero parameters, so the schema provides no parameter documentation. The description compensates by explaining what the tool reports and its scope, which is sufficient for a parameterless tool. The baseline for 0 params is 4, and the description meets that by clearly explaining the tool's output.

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?

The description clearly states the tool reports in-memory observability metrics for the server process, listing specific metrics (per-tool call count, error count/rate, latency, uptime, circuit-breaker state). It distinguishes itself from siblings by focusing on observability rather than configuration or resource management.

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?

The description explicitly states when to use it: 'Use it to spot a failing tool or a degraded portal upstream.' It also clarifies what it is not for: 'Metadata only — no payloads or secrets.' This provides clear guidance on when to invoke this tool versus alternatives.

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

get_referencesWho references this record?A
Read-only

Read-only dependency query for a record, both directions: dependents = records that would break if this one were deleted (the same analysis the delete gate runs — pages placing a block, queries reading a datasource, blocks bound to a query, system defaults), and references = records THIS one points at, each flagged exists:false when dangling. Use it before a delete/rename, or to trace where a datasource/query is used.

NameRequiredDescriptionDefault
idYesRecord id.
resourceYesResource type. Call describe_resource for fields and supported verbs.

Output Schema

NameRequiredDescription
idYes
noteYes
resourceYes
dependentsYes
referencesYes

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 the description reinforces this with 'Read-only dependency query'. It adds valuable behavioral context beyond annotations by describing both directions, the dangling reference flag (`exists:false`), and its relationship with the delete gate. This meaningfully extends what the annotations convey.

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?

The description is concise but information-dense. The first phrase 'Read-only dependency query' establishes intent upfront, and the rest explains behavior without redundancy. Every clause adds useful details: both directions, breakage semantics, examples, and use cases.

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?

Given the rich annotations, fully documented input schema, and the presence of an output schema, the description covers everything an agent needs to select and call this tool correctly. It explains the main use cases and the meaning of the returned fields without relying on external documentation.

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?

Input schema coverage is 100%, so the schema already documents both `id` and `resource`. The description adds context around the kind of record (e.g., datasource, query) but does not explain parameter specifics beyond what the schema provides. Baseline 3 is appropriate.

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?

The description states a specific verb ('query'), a precise resource ('a record'), and clearly defines the two result categories (`dependents` and `references`) with concrete examples. This distinguishes it from sibling tools like get_rules or find_resource by showing exactly what the tool returns.

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?

The description explicitly tells when to use it: before a delete/rename or to trace usage of a datasource/query. It also frames the dependents list as 'the same analysis the delete gate runs', which communicates a clear purpose and context where this tool is the right choice.

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

get_resourceGet one resource recordA
Read-only

Fetch a single record of a resource by its id (or name, for tags). Control the token cost: summary:true returns an overview (bulk fields become size stats — a block drops ~2,750 → ~150 tokens); fields:[…] returns just those top-level fields (+ id). Omit both for the full record.

NameRequiredDescriptionDefault
idYesRecord id (the resource's id_param from describe_resource).
fieldsNoReturn only these top-level fields (+ the record's id). Cheaper than the full record.
summaryNoReturn an overview: identity fields verbatim, bulky fields as size stats with a head preview.
resourceYesResource type. Call describe_resource for fields and supported verbs.

TDQS

A4.4/5.0
Behavior4/5

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

The annotations already declare readOnlyHint=true and openWorldHint=true, so the description doesn't need to restate safety. It adds significant behavioral value by explaining how the summary mode transforms bulky fields into size stats, including a concrete example (block drops ~2,750 → ~150 tokens). This goes beyond the schema by revealing the token-cost impact, which is not visible from the annotations or schema. The description doesn't contradict annotations.

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?

The description is concise, well-structured, and front-loaded with the core purpose. The token-cost guidance is placed after the main action, making it easy to scan. Every sentence adds value, with no redundant filler. The example of token reduction is a high-impact detail delivered efficiently.

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 fetch tool with 4 parameters, the description covers the key decision points: how to control token cost via summary and fields, and the id vs name distinction for tags. The output schema is absent, so the description should clarify what the return value looks like; it does partially by describing summary and fields outputs. However, it doesn't mention error cases or how to know which resource types support name-based lookup, but given the complexity and the schema's completeness, this is adequate.

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?

The schema's description coverage is 100%, so every parameter is documented there. The description adds some extra meaning by explaining how 'fields' and 'summary' interact (e.g., fields returns only top-level fields plus id, summary returns overview with size stats). However, it doesn't fully clarify the relationship between summary and fields (e.g., can they be combined?), which is a limitation. Still, given high schema coverage, a baseline of 3 is appropriate, with modest increments from the added context.

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?

The description states a specific verb ('Fetch'), a resource ('a single record of a resource'), and identifies the key identifier ('by its id'). It also notes the special case for tags (name instead of id), which adds clarity. This clearly distinguishes it from sibling tools like list_resource and find_resource.

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?

The description explicitly explains when to use the summary and fields options to control token cost, and implicitly guides the choice between the full record versus cheaper variants. It contrasts with potential alternatives by focusing on fetching a single record versus listing or finding, though it doesn't explicitly name alternative tools. However, the guidance on option selection is strong, and the context is clear enough.

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

get_rulesGet active authoring rulesA
Read-only

Return the active block-authoring rules: per-rule enforcement severities and the conventions text. Read this to see what create_block/update_block will enforce.

NameRequiredDescriptionDefault

No parameters

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, so the read-only nature is covered. The description adds value by specifying the exact content (severities and conventions text) and relates it to the enforcement behavior of mutation siblings, beyond what annotations convey.

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 with zero redundancy. The first sentence states what is returned; the second directly tells the agent when to use it. All information is front-loaded and purposeful.

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 simple, parameterless read tool with readOnlyHint=true, the description fully covers what an agent needs to know: the tool returns the active rules and their enforcement context. No output schema exists, but the description outlines the return contents adequately.

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 has zero parameters, and the schema coverage is trivially 100% with no properties. Per the rubric, a score of 4 is the baseline for no-parameter tools; the description cannot add parameter meaning since none exist, but it does clarify the output content instead.

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?

The description states a specific verb ('Return'), a clear resource ('active block-authoring rules'), and enumerates the content ('per-rule enforcement severities and the conventions text'). It further ties the tool to create_block/update_block enforcement, differentiating it from sibling config and access 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?

Explicitly instructs to read this tool to understand what create_block/update_block will enforce, giving a concrete call-to-action. It does not mention when to avoid this tool or use alternatives, but the provided usage context is clear and sufficient.

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

get_user_accessGet a user's access (groups + permissions)A
Read-only

Return the groups a user belongs to and the permissions granted to them, in one call. The user record itself is get_resource resource="user" (id "me" = the authenticated user).

NameRequiredDescriptionDefault
user_idYesUser UUID.

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already provide readOnlyHint=true and openWorldHint=true, so the description is not expected to repeat safety information. The description adds that this is a combined lookup, but does not disclose error behavior, whether permissions are direct or effective, or any special values the tool accepts. This is acceptable but not particularly rich.

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?

The description is short and front-loaded with the main purpose. The second sentence provides useful routing context but is slightly ambiguous because the parenthetical about 'me' could be read as applying to get_user_access when it likely applies to get_resource. Overall it is efficient with minimal waste.

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 simple one-parameter read tool, the description gives a reasonable high-level summary of the return content (groups and permissions) and points to the correct sibling for raw user records. However, with no output schema, it does not specify the shape, whether permissions are resolved/inherited, or behavior for invalid user IDs, leaving some gaps for an agent.

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?

The input schema fully describes user_id as 'User UUID' with 100% coverage, so the baseline is 3. The description does not add significant parameter-level detail; the mention of 'me' as the authenticated user appears to refer to get_resource, not necessarily to this tool's user_id parameter. Thus the description adds no meaningful semantic value beyond the schema.

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?

The description clearly states the tool returns a user's groups and permissions in one call, with a specific verb ('Return') and resource ('a user's access'). It distinguishes itself from simple user-record retrieval by mentioning get_resource for the user record itself, making the tool's specific purpose unambiguous.

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?

The description implies when to use this tool: when you need both groups and permissions together. It also points to get_resource for the raw user record, which is a helpful alternative. However, it does not explicitly state exclusions or when not to use this tool, leaving some inference required.

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

get_versionGet portal version / capabilitiesA
Read-only

Fetch the portal version and about info — use it to gate version-specific endpoints (e.g. saved queries are 1.18+). To confirm the connection, call check_connection instead.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the description only needs to add behavioral context. It does so by noting the tool returns version and about info and is meant for gating. It doesn't contradict annotations and provides useful purpose beyond what annotations state.

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 short sentences, front-loaded with the primary purpose. The second sentence adds necessary usage guidance. No redundancy or fluff.

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?

The description is sufficient for a zero-parameter, read-only info tool. It explains the use case (gating) and distinguishes from check_connection. It could mention what 'about info' contains, but that's minor. Overall, it's complete enough.

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?

There are no parameters, so the schema is trivially 100% covered. The description adds no param semantics but none are needed. Baseline for zero-parameter tools is 4; it doesn't lose points.

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?

The description states a specific action ('Fetch the portal version and about info') and clearly distinguishes it from check_connection by noting it gates version-specific endpoints. The resource is unambiguous and the tool's role is clear.

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?

It explicitly states when to use (gate version-specific endpoints) and when not to (to confirm connection, call check_connection instead). This gives the agent clear decision criteria and an alternative tool name.

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

list_resourceList a resource collectionA
Read-only

List records of a resource (block, datasource, layout, query, theme, partial, user, group, db_modification, etc.). Use this for discovery — e.g. find a datasource UUID before authoring a block. Always returns the paged envelope { total, offset, limit, returned, truncated, records } (default page size 100, max 500) — check truncated and walk offset for the rest. Optional query adds URL query params. First pages (offset 0) fetch SERVER-SIDE when the portal honors ?limit — total is then null while truncated=true (walk until truncated=false; the portal didn't send a count). Pages are also BYTE-capped (PORTAL_LIST_BYTE_CAP, default 60k chars): an oversized page auto-projects to { id, name } and says so in note — prefer only_names/fields for discovery and get_resource (summary/fields) for detail.

NameRequiredDescriptionDefault
limitNoMax records to return (default 100, max 500; paginates client-side).
queryNoOptional query-string params passed to the portal, e.g. { only_names: true }.
fieldsNoProject each record to these top-level fields (+ id) — e.g. ['name','updated_at'] to grab concurrency tokens cheaply. Takes precedence over only_names.
offsetNoRecords to skip (pagination).
resourceYesResource type. Call describe_resource for fields and supported verbs.
only_namesNoProject each record to just { id, name } — cheap discovery, works regardless of portal support.

Output Schema

NameRequiredDescription
noteNo
limitYes
totalYesnull = unknown (server-side page; the portal sent no count)
offsetYes
recordsYes
resourceYes
returnedYes
truncatedYes
auto_projectedNo

TDQS

A4.8/5.0
Behavior5/5

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

Annotations carry only readOnlyHint and openWorldHint; the description carries the real burden and nails it, disclosing non-obvious runtime behavior the annotations can't: nullable `total` when first pages fetch server-side, the walk-until-truncated=false protocol, byte-capping at PORTAL_LIST_BYTE_CAP with silent auto-projection to { id, name } plus a `note` field. These are exactly the pagination and envelope edge cases that would cause silent agent bugs, and they go well beyond what readOnlyHint/openWorldHint 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?

Dense but purpose-built: a single paragraph that moves logically from what → when → return contract → edge cases → routing, with the most important fact (purpose + example) front-loaded. The one blemish is that the sentence 'Optional `query` adds URL query params' largely restates the schema, and the wall of nested parentheses is heavy on the eyes. For a tool this complex (6 params, byte caps, portal variability), the density is earned.

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?

Given the tool's complexity — open-world portals, client- vs server-side pagination, byte caps, an 18-value enum, and a self-described output envelope — the description covers every call-relevant dimension: the exact envelope { total, offset, limit, returned, truncated, records }, how to iterate, what total:null means, how to detect truncation, and when to route elsewhere. No return-format gap exists because the description dually serves as de facto output documentation (the envelope is described inline even though an output schema is flagged). An agent could implement correct pagination and projection entirely from this text.

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. The description clears that bar by adding behavioral consequences tied to parameters that the schema doesn't state: when to prefer only_names/fields for discovery, the interplay between byte caps and field projection, and the fact that `query` lets the portal (not just the client) do the work. It stops short of adding a 5 because the schema already carries its weight with examples like { only_names: true } and ['name','updated_at']; the description refines rather than rescues the parameter docs.

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?

Specific transitive verb plus explicit resource scope ('List records of a resource (block, datasource, layout, ...)') with the 18-value enum in the schema to back it up. It differentiates from siblings by naming its role — 'Use this for discovery — e.g. find a datasource UUID before authoring a block' — and explicitly distinguishes itself from get_resource ('...for detail') and describe_resource ('Call describe_resource for fields and supported verbs'). An agent can select this tool for listing/discovery and route detail work elsewhere.

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 explicit when-to-use ('Use this for discovery') with a concrete workflow example, and names the alternative with the condition that selects it: 'prefer only_names/fields for discovery and get_resource (summary/fields) for detail.' It also documents how to fully consume the result set ('walk offset for the rest'), so the agent knows the shape of the interaction, not just when to fire it. This is explicit routing guidance, not implicit inference.

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

migration_preflightMigration preflight probe (read-only)A
Read-only

Empirical migration audit of the connected portal — run BEFORE writing any conversion pattern. Covers every block by FUNCTION, not just scripted ones: classifies each placed block (scripted/template/markup/native-widget), scans EVERY code- and config-bearing field (not just the html body) for legacy patterns — comment/string-aware so a commented-out call doesn't drive scope — flags hardcoded portal origins (environment portability), maps placement through layouts AND partials AND snippets (an 'orphan' is unreachable through all three), and preflights every bound query: does it execute, does it return column metadata, are numeric columns delivered as strings, is the STORED column metadata stale (repair_query_metadata fixes that). Also returns the browser-probe checklist for the runtime questions a server-side scan cannot answer. Read-only.

NameRequiredDescriptionDefault
limitNoCap per-block detail entries returned (default 100). Full counts are always reported.
max_queriesNoCap on queries to execute for the data preflight (default 25).
execute_queriesNoPreflight bound queries by executing each once (default true). Set false for a cheap structural-only pass.

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the description doesn't need to restate safety. It adds valuable behavioral context: comment/string-aware scanning, classification of blocks, mapping through layouts/partials/snippets, and the fact that it executes queries (which is a side-effect despite read-only intent). It also discloses that it returns a browser-probe checklist, which is beyond the schema. Minor deduction: it doesn't explicitly state that executing queries may have performance implications, but the read-only annotation covers the safety profile.

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?

The description is dense but front-loaded with the most important usage guidance ('run BEFORE writing any conversion pattern'). Every sentence adds substantive detail about scope, coverage, and behavior. It's long, but the complexity of the tool justifies it. Slight deduction for being a wall of text without paragraph breaks, which could be structured better.

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 complex audit tool with 3 optional parameters, 100% schema coverage, and read-only annotations, the description covers everything an agent needs: what it audits, how it classifies, what it flags, how it handles queries, and what it returns (including the browser-probe checklist). No output schema exists, so the description's mention of return contents is essential and sufficient. Nothing critical is missing.

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 schema already documents all three parameters well. The description adds context by explaining the trade-off between structural-only and full preflight (via execute_queries), and clarifies that limit caps per-block detail entries while full counts are always reported. This goes beyond the schema's terse descriptions, so a 4 is warranted.

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?

The description states a specific verb ('run') and resource ('migration preflight probe'), and clearly distinguishes it from siblings by emphasizing it is an empirical audit that covers every block by function, not just scripted ones. It names the sibling repair_query_metadata as a fix for stale metadata, which helps differentiate.

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?

The description explicitly says 'run BEFORE writing any conversion pattern', giving a clear temporal usage condition. It also implies when not to use it (when you need to fix stale metadata, use repair_query_metadata instead) and contrasts with structural-only passes via the execute_queries parameter. This is strong guidance.

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

namingNaming convention (suggest / parse)A
Read-only

The SCOPE · Kind Subject naming convention as a pure function. action=suggest generates a conforming display name, stable slug and facet tags from parts (kind required; scope accepts a code or facet tag: HC=healthcare, FIN=financial, SC=supply-chain, RT=retail, IOT=iot, CRM=crm, MKT=marketing, EXEC=executive, SYS=system, DW=data-warehouse, TMP=scratch; kind is one of: kpi, chart, table, filter, hero, navigation, map, text, page, partial, query, datasource, theme — resource kinds like datasource/query/page omit the kind word from the display name). action=parse decomposes an existing display name (name required) and grades conformance. Prefer suggest over hand-naming so names — and the slugs/tags derived from them — stay consistent.

NameRequiredDescriptionDefault
kindNosuggest (required): content kind — kpi, chart, table, filter, hero, navigation, map, text, page, query, datasource, theme…
nameNoparse: the display name to decompose, e.g. 'HC · KPI Band'.
scopeNosuggest: scope code (e.g. HC, DW) or facet tag (e.g. healthcare).
actionYessuggest = build a name from parts; parse = decompose/grade a name.
sourceNosuggest: data-asset source facet for datasources/queries — sample, live, telemetry, curated, or reference. Adds a '— <Source>' marker + tag; omit to leave a name unmarked (the 'live' default).
subjectNosuggest: human subject phrase, e.g. 'Revenue by Department'.
qualifierNosuggest: optional variant/grain, e.g. 'YTD' or 'by-region'.

TDQS

A5/5.0
Behavior5/5

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

The description calls the tool a pure function, which adds determinism/no-side-effect context beyond the readOnlyHint annotation. It also discloses useful behaviors: stable slugs, facet-tag generation, resource kinds omitting the kind word, source markers with a 'live' default, and conformance grading. No contradiction with 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.

Conciseness5/5

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

The description is dense but front-loaded with the core convention and both actions. Every sentence earns its place, and the long enumerations are necessary because the schema does not provide them.

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 two-mode tool with seven parameters and no output schema, the description provides enough to call it correctly: required fields per action, all allowed vocabularies, source default behavior, and what each mode returns at a conceptual level. The exact parse grading rubric is not needed for selection or invocation.

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?

The schema covers parameter names, but the description supplies the full controlled vocabularies it omits: scope code mappings, the complete kind list, source facets, and the conditional omission rule for resource kinds. It also clarifies requiredness per action, which goes meaningfully beyond the input schema.

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?

The description states the exact function: the `SCOPE · Kind Subject` naming convention as a pure function, with suggest generating a display name, slug, and tags, and parse decomposing and grading a name. It clearly distinguishes the two modes and is unlike any of the resource/config sibling tools.

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?

It explicitly says to prefer suggest over hand-naming and explains why: consistency of derived slugs and tags. It also makes the parse mode's purpose obvious for existing display names, so an agent can select the right action without guessing.

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

place_blocksPlace blocks on a page (declarative)A
Idempotent

Declaratively manage which blocks a page (layout) shows, in ONE atomic read-modify-write. mode=merge (default): upsert the blocks entries (re-placing updates position) and remove any ids in remove; other blocks on the page are untouched. mode=replace: the page becomes EXACTLY the blocks list (requires confirm:true; customized grid.layouts, hidden flags and geometry of surviving blocks are preserved). Each entry: { block_id, position?, height?, hidden? }. An entry with NEITHER position NOR height keeps an already-placed block's current geometry (safe for hidden-only toggles); a NEW block with no position auto-stacks full-width below existing content in array order; pass position (or height) to re-place explicitly. Blocks are placed, not created (create_block first) and never deleted (delete_resource does that). dry_run:true previews the final grid without writing. GRID BUDGET: every box is a % of the page's grid.layouts.{bp}.height (default 100), and blocks stack by accumulating top — so Σ(heights) must stay <= the grid height or the page CLIPS silently. The auto-place default is 50%, so THREE defaulted blocks already overflow: pass an explicit height for each. Budget guide at 100: filter bar 8-10, KPI band 18-22, chart card 30-35, table 35-40. Pair blocks side by side (same top, width 50 each) to buy vertical room before making the page taller, and aim to land everything above the fold at lg (the portal's header/footer/sidebars already take their share). If it truly won't fit, raise the grid height in increments of 25 (100 -> 125 -> 150) via update_resource. The response reports overflow when content exceeds the grid.

NameRequiredDescriptionDefault
modeNomerge (default) = upsert/remove listed blocks only; replace = page becomes exactly `blocks`.
blocksNoBlocks the page should show, applied in order (auto-placed entries stack top-to-bottom).
removeNoBlock UUIDs to take OFF the page (merge mode only; the block objects are not deleted).
confirmNoRequired true when mode=replace (it drops every block not in the list).
dry_runNoCompute the final grid and run every gate without writing.
layout_idYesLayout (page) UUID.
expected_updated_atNoOptimistic-concurrency token: the layout's updated_at from your read. Refuses with a conflict if the page changed in between (e.g. a parallel loop) — re-read, re-apply, retry.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare readOnlyHint:false, destructiveHint:false, idempotentHint:true. The description reinforces these honestly (no contradiction: dry_run writes nothing, replace doesn't destroy blocks, merge is repeatable) while adding genuinely new behavioral disclosure beyond annotations: auto-stack fallback, clipping when Σ(heights) exceeds budget, preservation of optimized geometry, and the overflow field in the response. It even warns about parallel-loop conflicts via expected_updated_at. No hidden surprises are left implicit.

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?

The description is dense and information-rich — it earns its length with concrete values (50% default, budget guide, step sizes of 25), and it front-loads the most important facts (atomicity, mode semantics) before the budget guide. It loses half a point for length: at 700+ words it's on the edge of what a description should hold, and a few items (e.g., the within-paragraph 're-read, re-apply, retry') could be trimmed without loss. Still, structure is excellent: every sentence adds information and the flow from purpose → modes → edge cases → budgets → fallback plan is logical.

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 tool this complex (7 params, 2 modes, atomic RMW, geometry placement, budget constraints, concurrency), the description is thorough: it covers failure modes (clipping), feedback (overflow in response), preview (dry_run), checked confirmation for destructive replace, and forward-migration guidance (raise grid height via update_resource). The schema's own text (descriptions on blocks, position, etc.) carries its weight, but the description doesn't rely on it — everything an agent needs to call place_blocks safely and effectively is within reach. Output-schema absence is not a gap here.

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 description coverage is 100%, so the schema already documents each parameter individually. The description adds meaningful cross-parameter interactions (position+height precedence rules, 'an entry with NEITHER position NOR height keeps an already-placed block's current geometry', auto-stack ordering) that give value beyond the schema. The grid-budget guidance (e.g., 'filter bar 8-10, KPI band 18-22, chart card 30-35, table 35-40') is excellent proactive guidance, though the schema already covers some of this, so this is a strong 4, not quite a 5 (which would be reserved for a tool whose schema did none of this).

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?

The description opens with a crisp verb+resource statement ('Declaratively manage which blocks a page (layout) shows, in ONE atomic read-modify-write') that immediately conveys both function and scope. It explicitly names its own boundaries with sibling guidance integrated inline: 'Blocks are placed, not created (create_block first) and never deleted (delete_resource does that).' An agent could select this tool without ambiguity among 40+ siblings.

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?

Every non-obvious behavior is scoped to exact mode semantics: merge = upsert/remove only; replace = page becomes EXACTLY the list (confirm:true required). The description also covers edge cases (preservation of grid.layouts, hidden flags, geometry of surviving blocks) and names the sibling tools that own related concerns (create_block, delete_resource, update_resource, dry_run preview). An agent could decide when to branch to mode=replace vs merge with no further help.

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

profile_datasourceProfile a datasource (stats + sample rows)A
Read-only

Sample a datasource and return per-column statistics — inferred type, non-null/empty counts, distinct value count, sample distinct values for categoricals, and min/max for numerics — PLUS raw sample rows (sample.columns + sample.rows) so you see real column names and literal values in the same call. Exactly what you need to design filters, choose chart dimensions, pick aggregations, and match a block's column constants to reality. Profiles over a sample (default 500 rows); sample_rows caps the raw rows returned (default 10, 0 for stats only).

NameRequiredDescriptionDefault
sample_rowsNoRaw rows to return alongside the stats (default 10, max 50, 0 = none).
sample_sizeNoRows to sample for the profile (default 500, max 5000).
distinct_capNoStop counting distinct values past this many per column (default 100).
datasource_idYesDatasource UUID.

TDQS

A4.5/5.0
Behavior5/5

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

The annotations already declare readOnlyHint: true and openWorldHint: true, so the description does not need to reiterate side effects. The description itself is transparent about the operation: it samples and returns statistics and rows, implying no modifications. There is no contradiction between the description and annotations, and the description adds detail about the read-only nature by using the verb 'sample'.

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

Conciseness3/5

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

The description is verbose and contains redundant phrasing. For example, it repeats 'so you see real column names and literal values in the same call' and then again 'match a block's column constants to reality.' The em-dash style and the extra explanatory sentence ('Exactly what you need...') could be condensed. While not overly long, it lacks conciseness and could be streamlined without losing meaning.

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?

The description thoroughly explains what the tool returns (per-column stats and sample rows) and its purpose. However, it does not mention error scenarios, limits beyond parameter defaults, or how the results are formatted. Since there is no output schema, the description partially compensates by describing the output structure, but it could be more comprehensive regarding edge cases (e.g., empty datasource, large datasets). Overall, it is sufficient for a typical agent interaction.

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?

All four parameters are fully described in the schema with clear meanings: datasource_id, sample_size, sample_rows, and distinct_cap each have detailed descriptions. The schema coverage is 100%, and the descriptions provide sufficient context (e.g., 'Stop counting distinct values past this many per column'). No additional clarification is needed in the tool description beyond what is already provided.

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?

The description clearly states the tool's purpose: sampling a datasource and returning per-column statistics plus raw sample rows. It explicitly lists what is returned (inferred type, non-null/empty counts, distinct value count, sample values, min/max) and explains the benefit ('so you see real column names and literal values'). This is specific and unambiguous, distinguishing it from generic resource inspection 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?

The description includes a clear use case: 'Exactly what you need to design filters, choose chart dimensions, pick aggregations, and match a block's column constants to reality.' This indicates when to use the tool, though it does not explicitly contrast with sibling tools like describe_resource or list_resource. It implies a data profiling context, which is sufficient guidance for an agent to select it appropriately.

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

reload_configReload configuration from diskA
Idempotent

Drop every in-process config cache and re-read config from disk (project .zuar-portal/config.json, bundle config, env-derived settings), resetting the portal HTTP session. Use after MANUALLY editing a config file — edits to the already-loaded project file are also picked up automatically (mtime-aware), but a NEWLY CREATED config file or bundle/env change needs this. Note: tool-surface gating is registered at startup and still needs a server restart to change.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare idempotentHint=true and destructiveHint=false)Skip; the description adds behavioral context: it resets the HTTP session DNS, drops caches, and notes tool-surface gating requires a server restart. This goes beyond annotations and warns of a side effect (session reset) that agents need to know, without contradicting structured hints.

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?

The description is a single dense paragraph that front-loads the core action (drop caches and re-read) and then adds usage context. Every sentence provides a distinct piece of info (what resets, when to use, auto-load caveat, restart requirement). Slightly long but each part earns its place.

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 parameters and no output schema, the description must stand on its own. It explains the full behavior (cache drop, re-read from disk, session reset), when to call it, and the automatic pickup nuance. It doesn't spell out the return value, but for a side-effecting reload tool that is acceptable. Complete for its complexity.

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?

There are zero parameters, so the input schema provides no semantics to extend. The description correctly avoids inventing parameters and instead documents the tool's behavior and the conditions for its use, which is the appropriate compensation.

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 action (drop caches, re-read config), names the specific config sources explicitly (.zuar-portal/config.json, bundle config, env-derived settings), and clearly distinguishes it from a passive load or update. It also mentions resetting the HTTP session, which differentiates it from get_config/update_config siblings.

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?

Explicitly states when to use (after manually editing config) and what is auto-picked-up (mtime-aware automatic reload for existing files). It identifies the triggering condition for a newly created config file or bundle/env change, giving clear use cases. It does not name alternatives like get_config, but the guidance is sufficient for an agent to decide.

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

repair_query_metadataRepair a saved query's column metadataA
Idempotent

Re-introspect and store a saved query's COLUMN METADATA without touching its SQL or datasource binding — safe by construction (name/datasources/raw_sql/sql_form are re-sent verbatim; only columns is refreshed from a live execution). Stale stored metadata makes bound blocks render blank/wrong after schema or version moves; migration_preflight flags it as stored_metadata_stale. Dry-run by default: reports the stored-vs-live diff; pass apply:true to write. Round-trip verifies the write and mirrors it to version control.

NameRequiredDescriptionDefault
applyNoWrite the refreshed metadata (default false = report the diff only).
paramsNoParameters for a parameterized query, as a { name: value } map.
query_idYesSaved query UUID.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare idempotent and non-destructive; the description adds depth: re-sends other fields verbatim, dry-run by default, apply:true required to write, round-trip verification, and version-control mirroring. No contradiction with 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 sentences, each serving a distinct purpose: action, rationale, behavior. It's front-loaded and efficient, though slightly dense; a minor tightening would make it a 5.

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?

Complete for an agent: explains what it does, when to use it, how to invoke the write (apply:true), and what to expect (diff report, write verification). Lacks explicit output schema but the description provides enough for correct invocation.

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 covers all 3 params with descriptions, so baseline is 3. The description adds value by clarifying the dry-run semantics of apply (default false) and that params is for parameterized queries, enhancing the schema.

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?

Clearly states the action (re-introspect and store column metadata) and the resource (saved query), and explicitly enumerates what it does NOT touch (SQL, datasource binding). This scoping differentiates it from sibling tools without naming them.

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 a concrete trigger condition (migration_preflight flags stale metadata) and explains the dry-run/apply workflow. It implies when not to use it (when you need to change SQL or datasource) but doesn't explicitly name alternatives.

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

restore_resourceRestore a record to a previous versionA

Revert a content record — or a datasource — to a prior committed version and write it back through the same gated write path as any other update (a DELETED block is recreated under its old id; a datasource restore needs data writes enabled). Omit ref to undo the most recent change, or pass a commit hash from vc_log; inspect it first with vc_diff. The restore is itself committed. Requires PORTAL_VC_DIR. NOT covered (never snapshotted): users, groups, permissions, credentials, api_keys, system records, db_modifications.

NameRequiredDescriptionDefault
idYesRecord id.
refNoGit commit hash/ref to restore from. Default: the version before the latest change to this record.
resourceYesRecord kind: 'block', a content resource key (layout, query, theme, partial, snippet, translation, dashboard, tag), or 'datasource'.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond annotations, the description reveals that the restore writes through the gated write path, is itself committed, recreates DELETED blocks under their old id, and requires PORTAL_VC_DIR. It also defines the open-world boundary by naming never-snapshotted record kinds. This does not contradict 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.

Conciseness5/5

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

The core action is front-loaded, and every clause adds useful detail: side effects, prerequisites, source of ref, and exclusions. Despite its density, there is no redundant text, making it appropriately sized for the tool's complexity.

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, the description covers prerequisites, side effects, ref sourcing, and unsupported resources. The only notable omission is the return/response behavior, which the absence of an output schema leaves to inference.

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 schema already documents all three parameters with 100% coverage, so the baseline is 3. The description adds operational meaning by explaining the default ref behavior ('the version before the latest change'), pointing users to vc_log for valid refs, and clarifying datasource requirements.

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?

The description states a specific action ('revert... to a prior committed version'), the target resources ('content record or a datasource'), and the write-back effect. This clearly distinguishes restore_resource from inspection siblings like vc_diff and vc_log.

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?

It gives explicit when-to-use guidance: omit ref to undo the latest change, or pass a commit hash from vc_log after inspecting with vc_diff. It also names prerequisites (PORTAL_VC_DIR, data writes enabled for datasource) and lists unsupported resource types, which tells an agent when not to use the tool.

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

run_db_modificationRun a database modificationA
Destructive

Execute a saved db_modification (INSERT/UPDATE/DELETE) by name. This WRITES to a database — and database writes have NO snapshot/rollback, unlike portal content. Requires data writes enabled (PORTAL_ALLOW_DATA_WRITES=1) and confirm=true. Refuses an unscoped mass write (UPDATE/DELETE/MERGE without a real WHERE — 1=1 doesn't count — TRUNCATE, DROP, ALTER…DROP, GRANT/REVOKE) unless allow_unfiltered=true; the check is a best-effort classifier and fails closed if the SQL can't be inspected. Pass params as a { name: value } map, or params_list for bulk rows.

NameRequiredDescriptionDefault
nameYesdb_modification name to run.
paramsNoSingle-row parameters as a { name: value } map.
confirmYesMust be true to actually run — guards against accidental DB writes.
autocommitNoCommit each statement (default portal behavior).
params_listNoBulk parameters: a list of { name: value } maps, one per row.
allow_unfilteredNoMust be true to run an UNSCOPED mass write (UPDATE/DELETE without WHERE, TRUNCATE, DROP). Default false.
ignore_sql_errorsNoContinue past SQL errors.

TDQS

A4.6/5.0
Behavior5/5

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

The description extensively discloses behavioral traits beyond annotations: no snapshot/rollback for database writes, the need for confirm, the guard against unscoped writes, and the best-effort classifier that fails closed. This aligns with annotations (destructiveHint=true, readOnlyHint=false) and adds crucial risk context an agent needs.

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?

The description is compact but dense, with the primary action stated first, followed by critical constraints and parameter usage. Every sentence contributes meaningful information (prerequisites, safety checks, parameter formats). It's not bloated, but slightly longer than necessary; still excellent.

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?

Given the tool's complexity (7 params, safety guards, no output schema), the description covers all essential aspects: the operation, prerequisites, guard behavior, parameter passing, and failure modes. An agent has enough information to invoke it correctly and understand risks without further reference.

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% with descriptions for all params. The description adds value by explaining the semantics: params is a { name: value } map, params_list is for bulk rows, confirm guards against accidental writes, and allow_unfiltered is required for mass writes. This enriches the structured schema details.

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?

The description states a specific verb (execute) and resource (saved db_modification), and clarifies it's for INSERT/UPDATE/DELETE operations. It clearly distinguishes from siblings like execute_query (which likely reads) by emphasizing it writes to a database, and the 'by name' scoping differentiates from other modification 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?

Explicit usage conditions are given: requires data writes enabled (PORTAL_ALLOW_DATA_WRITES=1), confirm=true, and describes when it refuses to run (unscoped mass writes without allow_unfiltered=true). While it doesn't name alternative tools, it provides clear prerequisites and boundary conditions, making it good but not perfect.

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

score_portalScore portal quality (blocks + pages, with baseline delta)A
Idempotent

Score every block and page 0–100 on what is MECHANICALLY checkable — authoring-rule violations, dangling query bindings, orphaned blocks, naming-convention fit, SELECT * bindings, oversized HTML, unscoped CSS, page overflow and dangling placements. 100 means 'nothing mechanically wrong', NOT 'well designed' — visual/business judgment stays with review agents. Scratch-marked records are excluded (cleanup_scratch handles them). With version control on, compares against the last saved baseline (improved/regressed/added/removed per record) — the loop discipline: score, improve, re-score, and only update_baseline=true after a verified improvement.

NameRequiredDescriptionDefault
detail_belowNoFull deduction detail only for scores below this (default 90); higher scores report one line.
update_baselineNoSave these scores as the new baseline in the VC mirror (requires PORTAL_VC_DIR).

TDQS

A4.3/5.0
Behavior4/5

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

Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description reveals that scratch-marked records are excluded, that it compares against a baseline when version control is on, and that 100 has a specific meaning. These are meaningful behavioral traits not covered by annotations. It does not mention potential side effects beyond baseline updates, but the annotations reduce the burden.

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?

The description is a single dense paragraph that packs essential information without fluff. Every sentence contributes: scope, exclusions, baseline behavior, and the meaning of 100. It is slightly long but well-organized, with the core purpose front-loaded. The structure is functional, though it could be broken into list form for easier scanning.

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?

Given there is no output schema, the description implicitly states what the tool returns (scores and baseline deltas). It covers key prerequisites like version control on for baseline, and mentions the detail_below behavior. It doesn't explicitly state the output format or error handling, but for a scoring tool with simple boolean and integer parameters, the information is largely sufficient to invoke it correctly.

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 schema already documents both parameters fully (coverage 100%), so the baseline is 3. The description adds extra meaning for update_baseline by explaining the loop discipline and when to set it to true, which goes beyond the schema's simple 'save as baseline' note. However, it duplicates the detail_below description from the schema, so the net addition is moderate.

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?

The description clearly states the tool's function: 'Score every block and page 0–100 on what is MECHANICALLY checkable' with a specific list of checks. It distinguishes itself from siblings by excluding scratch-marked records and referencing cleanup_scratch, and clarifies that 100 does not mean 'well designed' – a key scope distinction.

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?

It provides context on when to use the tool (for mechanical scoring) and when not to (scratch records go to cleanup_scratch). It also explains the loop discipline 'score, improve, re-score, and only update_baseline=true after a verified improvement', which guides the agent on when to set the baseline parameter. However, it does not explicitly compare with validate_portal or other similar validation tools, so alternatives are only partially addressed.

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

set_user_accessSet a user's access (groups and/or permissions)A
DestructiveIdempotent

Replace a user's group membership and/or permission set — pass groups, permissions, or both; each provided list is a FULL REPLACE (not additive), an omitted one is untouched. Requires admin writes enabled (PORTAL_ALLOW_ADMIN_WRITES=1) and confirm:true. dry_run:true reports the current access next to the proposed lists without writing. Stripping YOUR OWN admin access is refused unless allow_self_lockout=true.

NameRequiredDescriptionDefault
groupsNoComplete list of group ids the user should have (full replace).
confirmYesMust be true — each provided list REPLACES that entire membership.
dry_runNoReport current vs proposed access without writing.
user_idYesUser UUID.
permissionsNoComplete list of permission ids the user should have (full replace).
allow_self_lockoutNoMust be true to remove your OWN admin group/permission — after that you may not be able to undo anything.

TDQS

A4.7/5.0
Behavior5/5

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

Even with annotations indicating destructive and idempotent behavior, the description adds critical specifics: FULL REPLACE semantics, omitted lists untouched, the exact environment variable, the confirm flag requirement, dry_run capability, and safety guard against self-lockout. It goes far beyond what annotations provide, explaining exactly what happens to each portion of the access definition.

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 efficient sentences carry all the essential information: the action, the semantics, and the safety requirements. It is front-loaded with the most critical behavior (FULL REPLACE) and uses the second sentence for critical constraints. The only minor issue is the typo 'PORTALLOW' instead of 'PORTAL_ALLOW', which could cause confusion but does not detract from overall clarity.

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 destructive, write-operation tool with 6 parameters and no output schema, the description covers all the key behaviors an agent needs: replacement semantics, requirements, dry run, and self-lockout protection. It doesn't explain return values, but that is absent from annotations yet likely not essential given the operation-focused nature. The safety and idempotency aspects are sufficiently addressed. The description is both complete and safe.

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 input schema already has 100% parameter description coverage with each parameter clearly documented (e.g., 'Complete list of group ids... full replace'). The description adds value by synopsizing the relationship between groups and permissions and clarifying the interaction with confirm and dry_run. It slightly exceeds the baseline by clarifying the high-level contract, though the schema already does most of the heavy lifting.

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?

The description clearly states the tool replaces a user's group membership and/or permission set, using the strong verb 'Replace' and the resource (user's access). It distinguishes itself from read-only siblings like get_user_access by explicitly framing it as a mutation. The core behavior of full replacement is front and center, making the tool's purpose immediately obvious.

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?

The description gives strong usage context: requiring admin writes (PORTALLOW_ADMIN_WRITES=1) and confirm:true, plus explaining dry_run for safe preview and self-lockout protection. It clearly implies when to use this tool (to change access) versus alternatives through its explicit scope. However, it does not explicitly name a sibling tool for comparison or state when NOT to use it, so it misses the highest tier.

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

snapshot_portalSnapshot portal content to gitA

Export every content resource (blocks + layouts/queries/themes/partials/snippets/translations/dashboards/tags) AND datasources to the version-control repo and commit. Run once to seed history, or anytime to capture a checkpoint. Verifies COVERAGE: staged counts are checked against live listings and any resource kind that failed to export is reported (a rollback snapshot that silently skipped saved queries is not a rollback). Requires PORTAL_VC_DIR.

NameRequiredDescriptionDefault
messageNoCommit message (default: 'snapshot').

TDQS

A4.1/5.0
Behavior4/5

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

The description adds material behavioral detail beyond the annotations: the coverage verification ('staged counts are checked against live listings'), the rollback caveat, and the prerequisite 'Requires PORTAL_VC_DIR.' It aligns with readOnlyHint=false and idempotentHint=false, and does not contradict any annotation. It goes beyond the basics expected for a mutation 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?

The description is dense but efficient, front-loading the core action ('Export every content resource... AND commit') before adding usage timing and behavioral caveats. Every sentence carries distinct value, though it could be broken into clearer sentences for readability. It is not verbose enough to warrant a 3, but not as crisp as the two-sentence example for a 5.

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 complex export/commit tool with multiple resource kinds and a coverage check, the description covers the essential facts: what is exported, when to use it, the verification mechanism, and the required environment variable. It doesn't describe return values, but there's no output schema. The missing 'message' parameter usage is covered by the schema, so the description is sufficiently complete for an agent to decide when and how to call it.

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% for the single optional 'message' parameter, which the schema already documents ('Commit message (default: 'snapshot')'). The description does not add any new meaning for this parameter, so the baseline of 3 is correct. The mention of PORTAL_VC_DIR is an environment variable, not a parameter, and doesn't enhance parameter understanding.

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?

The description states a specific verb ('Export'), resource scope ('every content resource... AND datasources'), and destination ('version-control repo and commit'). It clearly distinguishes itself from sibling tools like vc_status or vc_diff by describing a distinct snapshotting action, leaving no ambiguity about what this tool does.

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?

It provides explicit timing guidance ('Run once to seed history, or anytime to capture a checkpoint'). While it doesn't name alternatives or state when not to use it, the context is clear enough that an agent can choose this tool for snapshot creation without confusion. A 5 requires explicit when-not/alternatives, which is absent, so 4 is appropriate.

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

synthesize_themeSynthesize a portal theme from brand preferencesA
Read-onlyIdempotent

Turn brand preferences into a portal theme spec — a customProperties token map + css — WITHOUT creating anything. Give a website_url and it fetches the homepage (SSRF-guarded) to suggest brand colors when primary_color is omitted. Create the returned theme with create_resource resource="theme" body={ name, json_data: { customProperties, css } } (a normal VC-tracked content write); the response includes that exact call as create_with. The design_intake PROMPT walks a user through these choices conversationally.

NameRequiredDescriptionDefault
fontNoTypeface feel (default humanist).
modeNoLight or dark base (default light).
headerNoHeader preference (recorded in the brief).
radiusNoCorner-radius style (default rounded).
densityNoSpacing density (default spacious).
sidebarNoSidebar preference (recorded in the brief).
brand_nameNoBrand name; used to name the theme.
fetch_siteNoFetch the website to suggest colors (default true when website_url is set).
theme_nameNoName for the theme (defaults to '<Brand> <Light/Dark>').
website_urlNoBrand/website URL; fetched (SSRF-guarded) to suggest colors.
accent_colorNoAccent/secondary color (hex); derived from primary if omitted.
primary_colorNoPrimary brand color (hex, e.g. #1f6feb). Required unless website_url yields a suggestion.

TDQS

A4.1/5.0
Behavior5/5

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

The description goes beyond annotations by explaining side effects: it fetches the website (SSRF-guarded) only to suggest colors, and it explicitly states it does not create anything. This aligns with the readOnlyHint and provides transparency about the fetch operation and the purpose of generating a spec. It also clarifies the relationship with create_resource without overstepping.

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

Conciseness2/5

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

The description is overly verbose. It includes a full example of a create_resource call, mentions VC-tracked content write, and references the design_intake PROMPT—details that are not necessary for understanding the tool's core function. The first sentence is clear, but the subsequent expansion dilutes the message and could confuse an agent.

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?

The description covers the main workflow (fetch, suggest, generate spec, then create) and clarifies that the output is a spec for use with create_resource. It also notes the SSRF guard. However, it does not mention the output format or how the spec is returned, which could be a gap for agents that need to consume the result. Still, given the schema covers params, the description is largely complete.

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?

While the schema already documents each parameter thoroughly (100% coverage), the description adds meaningful relationships: it explains that website_url is fetched only when primary_color is omitted, and that brand_name is used to name the theme. However, it does not elaborate on all params (e.g., font, mode), but the schema descriptions already handle those, so the additional context is beneficial.

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?

The description clearly states the tool's function: 'Turn brand preferences into a portal theme spec' and explicitly notes it does not create anything. This is a specific verb-noun pair that distinguishes it from a creation tool, and the no-write intent is reinforced by the readOnlyHint annotation.

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 implies a workflow (fetch site, suggest colors, then create via create_resource) but does not explicitly state when to use this tool versus alternatives. It mentions the design_intake PROMPT but does not provide clear conditions or scenarios for invocation. More explicit guidance such as 'use this when you need to generate a theme spec' would improve clarity.

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

update_blockUpdate an HTML blockA
Idempotent

Update an existing HTML block by UUID. Only the fields you pass change — the server merges them over the current record, so an omitted ui_queries keeps the existing data binding. Authoring rules validate only your delta; violations the stored block already has are grandfathered to warnings, never blockers. dry_run:true previews the exact write.

NameRequiredDescriptionDefault
cssNoNew CSS.
dataNoLegacy query-config object — ignored by current portals; use ui_queries.
nameNoNew display name.
tagsNoTag list — replaces existing tags, unless merge_tags:true (then these are added).
typeNoBlock type. This server only handles HTML blocks, so it must be "html".html
accessNoNew access control object.
dry_runNoRun every gate and report the would-be write without updating.
block_idYesBlock UUID to update.
css_fileNoPath to a file holding the block's CSS; the server reads it into `css`. Same byte-exact guarantee and same root containment as html_file. Mutually exclusive with `css`.
html_fileNoPath to a file holding the block's HTML+JS; the server reads it into json_data.html. PREFER THIS over inlining large content: the bytes are read off disk byte-exact, so nothing is retyped and characters like em dashes or box-drawing cannot silently normalize. Mutually exclusive with json_data.html. Must resolve under the CWD, the VC dir, or a PORTAL_FILE_ROOTS entry.
json_dataNoNew widget/extra config.
merge_tagsNoMerge `tags` into the block's existing tags instead of replacing them — preserves functional tags (e.g. a nav 'Menu' tag). Default false.
ui_queriesNoReplacement query/datasource binding. Omit to keep the block's existing binding (it is preserved automatically); pass [] to explicitly unbind all queries.
expected_updated_atNoOptimistic-concurrency token: the block's updated_at from your read. Refuses with a conflict if the block changed in between — re-read, re-apply, retry.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already indicate mutation (readOnlyHint=false) and non-destructive nature (destructiveHint=false). The description adds valuable details beyond annotations: server-side field merging, delta-only validation with grandfathering of existing violations, and dry_run preview behavior. It does not mention error handling, authentication, or rate limits, but what it adds is meaningful and non-redundant.

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?

The description is two sentences, front-loaded with the core action and followed by key behavioral highlights. It is efficiently structured with no fluff, covering merge semantics, validation behavior, and dry_run in a compact form. Every sentence earns its place.

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?

Given the tool's complexity (14 parameters, nested objects) and lack of an output schema, the description covers the main behavioral aspects (merge, delta validation, dry_run) and points to the schema for parameter details. It does not mention the return value or error behavior, but the absence of an output schema makes it acceptable to rely on the schema for parameters. Overall, it is sufficiently complete for an agent to use it correctly.

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?

The schema description coverage is 100%, and each parameter is already well-documented (e.g., ui_queries, dry_run, merge_tags, html_file). The description summarizes overall behavior (merge, delta validation) but does not add per-parameter meaning beyond the schema. It also clarifies the omission semantics of ui_queries, but that is already present in the schema. Therefore, it meets the baseline of 3 but does not exceed it.

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?

The description states a specific action ('Update an existing HTML block by UUID') with a clear resource and identifier. It distinguishes itself from sibling create_block (which creates) and generic update_resource by targeting HTML blocks and using UUIDs. This is precise and unambiguous.

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?

The description provides clear context for use: updating an existing HTML block via UUID, with merge semantics and a dry_run option. However, it does not explicitly mention alternatives or when to choose this over other update/create tools, so it lacks explicit exclusion guidance but still offers strong contextual cues.

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

update_configUpdate portal configA
Idempotent

Set a value at a config path. path is the key path (array of strings); value is the new value; merge merges into an existing object instead of replacing. Portal-wide setting: requires admin writes enabled (PORTAL_ALLOW_ADMIN_WRITES=1) AND confirm=true; dry_run=true previews the current value without writing. The response returns previous_at_path — pass it back to revert. Pointing default_dashboard/theme_id at a missing record is refused.

NameRequiredDescriptionDefault
pathYesConfig key path, e.g. ["branding","title"].
mergeNoMerge into an existing object instead of replacing.
valueNoNew value (object, array, string, number, or boolean).
confirmNoMust be true to write — this changes the whole portal's config.
dry_runNoReport the current value at `path` and the would-be write, without writing.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations indicate readOnlyHint=false, destructiveHint=false, idempotentHint=true, and openWorldHint=true. The description adds significant behavioral context: it explains the write requires confirm=true, the dry_run behavior, the merge vs replace semantics, and the revert mechanism via previous_at_path. It also discloses that invalid references are refused. This goes beyond the annotations, which are sparse, and provides the agent with critical safety and operational details. The only minor gap is not explicitly stating that the tool is idempotent, but the description's mention of merge and revert implies it.

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?

The description is a single paragraph but packs a lot of information. It front-loads the core action ('Set a value at a config path') and then covers key behaviors. It's not overly verbose, but it could be slightly more structured (e.g., bullet points) for readability. However, every sentence earns its place, and the information density is high without being redundant.

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?

Given the tool's complexity (5 params, conditional write behavior, revert mechanism), the description covers the essential aspects: prerequisites, dry_run, merge, revert, and error conditions. There's no output schema, so the description's mention of previous_at_path is crucial. The only minor omission is not specifying the exact response format beyond previous_at_path, but that's acceptable given the tool's nature. Overall, it's complete enough for an agent to use correctly.

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 description coverage is 100%, so the schema already documents all parameters. The description adds value by explaining the relationship between parameters: confirm must be true for writes, dry_run previews without writing, merge modifies behavior, and the response includes previous_at_path for revert. It also clarifies the path format (array of strings) and gives an example. This is more than the schema provides, so it earns a 4 rather than a baseline 3.

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?

The description clearly states the tool's purpose: 'Set a value at a config path.' It specifies the resource (portal config) and the action (set/update), and distinguishes it from siblings like get_config and update_resource by focusing on config path manipulation. The description also mentions specific config keys (default_dashboard/theme_id) and the merge behavior, which adds specificity beyond the name.

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?

The description provides explicit conditions for use: requires admin writes enabled (PORTAL_ALLOW_ADMIN_WRITES=1) AND confirm=true, and mentions dry_run for previewing. It also notes that pointing at a missing record is refused, which is a clear constraint. While it doesn't explicitly name alternatives, the context of portal config vs resource updates is implied, and the conditions are specific enough to guide when to use this tool.

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

update_resourceUpdate a resource recordA
Idempotent

Update a record by id. Only the fields in body change; the server merges them over the current record (portal PUT is full-replace) so untouched fields are preserved. Same write gating as create_resource. For loop/parallel safety, pass expected_updated_at (the updated_at you saw when reading) — the write is then refused with a conflict if anyone changed the record in between, instead of silently overwriting their work.

NameRequiredDescriptionDefault
idYesRecord id to update.
bodyYesFields to change. Unknown fields are dropped.
dry_runNoRun every gate and report the exact merged body that would be written, without writing.
resourceYesResource type. Call describe_resource for fields and supported verbs.
expected_updated_atNoOptimistic-concurrency token: the record's updated_at from your read. Refuses with a conflict if the live record has moved — re-read, re-apply, retry.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations contain no safety flags (readOnlyHint=false, destructiveHint=false) and no concurrency hints. The description compensates fully: it discloses the merge semantics (only body fields change, untouched preserved), the write gating similarity to create_resource, the optimistic-concurrency behavior with conflict refusal, the dry_run behavior (runs gates, reports merged body without writing), and statement that unknown fields are dropped. This goes well beyond the annotations and is critical for a mutation tool.

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?

The description is three sentences, dense with information, and each sentence earns its place. Key operational guidance (merge vs full-replace, concurrency token) is front-loaded. No fluff, no repetition of schema. This is appropriately concise for a complex mutation tool.

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?

Given 5 parameters, no output schema, and rich semantics (merge, concurrency, dry_run), the description covers everything an agent needs: what the call does, how the merge works, how to avoid lost updates, what dry_run does, and the write gating. The sibling list helps the agent route to describe_resource for field details, which is referenced in the schema enum. No critical gaps are evident.

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 description coverage is 100%, so the schema already documents all 5 parameters. The description adds value beyond the schema by explaining the semantics of expected_updated_at (conflict refusal) and the merge behavior of body, which the schema only describes as 'Fields to change. Unknown fields are dropped.' The description clarifies the partial-update intent. This earns above baseline 3, but not 5 because the description doesn't add much about dry_run beyond the schema's 'Run every gate... without writing.'

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?

The description states a specific verb ('Update'), a resource ('a record by id'), and critically distinguishes partial update from the portal PUT full-replace behavior. It also names a sibling (create_resource) for write gating. This clearly differentiates from update_block/update_config and the read tools.

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?

Explicitly instructs when to use the optimistic-concurrency token (expected_updated_at) for loop/parallel safety, mentions the same write gating as create_resource, and contrasts with portal PUT full-replace. It provides clear context and an exclusion (portal PUT does NOT do partial merge), which helps the agent choose this over alternatives.

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

validate_blockValidate a block (no write)A
Read-only

Run the same authoring rules as create_block/update_block against a block payload WITHOUT writing it. Use it to iterate on HTML/JS/CSS until it's clean — it flags the footguns that only surface in a live browser (literal $ String.replace mangling, {{ }} interpolation, data polling, unscoped CSS, full docs, unsafe JS). Returns { valid, errors, warnings }. Pass against_block_id to preview GRANDFATHERING: errors the stored block already has are reported as pre_existing (update_block flags them as warnings instead of blocking).

NameRequiredDescriptionDefault
cssNoCSS section.
dataNoHTML/JS section (the block `data`).
nameNoBlock name (optional for validation).
css_fileNoPath to a file holding the block's CSS; the server reads it into `css`. Same byte-exact guarantee and same root containment as html_file. Mutually exclusive with `css`.
html_fileNoPath to a file holding the block's HTML+JS; the server reads it into json_data.html. PREFER THIS over inlining large content: the bytes are read off disk byte-exact, so nothing is retyped and characters like em dashes or box-drawing cannot silently normalize. Mutually exclusive with json_data.html. Must resolve under the CWD, the VC dir, or a PORTAL_FILE_ROOTS entry.
json_dataNoWidget/extra config.
ui_queriesNoQuery/datasource binding (this is how a block gets data — the portal has no `data` field). Array of { enabled, page_size, query_id, filter_strategy }, e.g. [{ "enabled": true, "page_size": 50, "query_id": "<query-uuid>", "filter_strategy": { "type": "blacklist", "value": [] } }]. The query_id must reference a saved query that already has a datasource attached. On update_block, the existing ui_queries is preserved automatically unless you pass a new value.
against_block_idNoExisting block UUID to compare against — splits errors into new vs pre-existing (grandfathered on update_block).

TDQS

A5/5.0
Behavior5/5

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

Annotations only declare readOnlyHint=true, but the description goes far beyond by detailing that it runs the same authoring rules without writing, returns a structured { valid, errors, warnings } object, and previews grandfathering behavior. It also enumerates specific footguns it detects, which is exactly the kind of behavior that annotations alone don't convey.

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?

The description is dense but every sentence earns its place: it front-loads the core purpose and then layers on behaviors like returned shape, grandfathering, and file-preference guidance. Formatting with em dashes and line breaks keeps it readable despite the length, and no information is redundant.

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 validation tool with no output schema, the description covers return shape, side-effect-free guarantee, the difference between validation and update behavior, and even hints at security/correctness concerns. It also guides on resource loading (file paths and root containment). The focus on this tool's specific role in the portal authoring flow makes it complete for an agent to use it correctly.

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 description coverage is 100%, so the baseline is 3, but the description adds significant value beyond the schema: it explains trade-offs (e.g., html_file 'byte-exact' and 'PREFER THIS over inlining'), clarifies relationships (html_file vs json_data.html), and provides a detailed example for ui_queries with notes on update semantics. This goes well beyond restating the schema.

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?

The description opens with a specific verb-resource pair ('validate a block payload') and immediately distinguishes it from siblings by referencing 'the same authoring rules as create_block/update_block'. It clarifies the key non-write behavior and names the exact sibling operations, making the tool's role unmistakable.

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?

It explicitly tells when to use this tool ('Use it to iterate on HTML/JS/CSS until it's clean') and explains the comparison to update_block via against_block_id, including how it interacts with grandfathering. It sets expectations about what will be flagged and contrasts with update_block's warning behavior, giving clear guidance on tool selection.

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

validate_portalValidate portal integrity (read-only)A
Read-only

Sweep every page (layout), partial, theme, query, block, db_modification and system record and report anything that would break or render wrong: structurally malformed records (e.g. a page missing grid.layouts — the 'all pages vanished' bug), dangling references (a page/block pointing at a deleted block/query/datasource), unscoped mass-write SQL (UPDATE/DELETE with no WHERE, TRUNCATE, DROP), and datasource hygiene (a name that leaks a connection-string/password, or a datasource reporting a broken connection). Fixes nothing — run it after bulk changes or on a schedule to catch latent breakage before users do.

NameRequiredDescriptionDefault
limitNoCap the number of issues returned (still reports the full counts). Omit for all.

TDQS

A4.3/5.0
Behavior5/5

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

The description discloses the full scope of the sweep (all listed resource types), the categories of issues (structural malformations, dangling references, unscoped mass-write SQL, datasource hygiene), and the 'Fixes nothing' behavior. It also mentions that with the limit param, 'still reports the full counts' (though not in the description text, the behavior is implied by the schema's description). This aligns perfectly with the readOnlyHint annotation and adds substantial context beyond it.

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?

The description is a single dense paragraph that front-loads the action and then enumerates checks. It is information-rich without rambling, but slightly long. Every clause adds value — no filler. It's concise enough given the complexity of the 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?

The description covers the resource types, the issue categories, and the non-destructive nature. It implies a report of issues and mentions that counts are still reported even when limited. There is no output schema, so the description should clarify return format; while it doesn't specify the exact structure, it's clear enough for an agent to expect a list of findings. The breadth of checks is well covered.

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?

The only parameter, limit, is fully documented in the schema with a clear description ('Cap the number of issues returned (still reports the full counts). Omit for all'). The tool description adds no additional semantic detail beyond what the schema already provides. Since schema coverage is 100%, baseline 3 is appropriate.

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?

The description opens with a specific verb and resource: 'Sweep every page (layout), partial, theme, query, block, db_modification and system record' — clearly a validation sweep. It enumerates the types of issues it catches, distinguishing it from siblings like validate_block (which is narrower) and repair_query_metadata (which fixes). The purpose is unambiguous and non-tautological.

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?

Explicit guidance is given: 'run it after bulk changes or on a schedule to catch latent breakage before users do.' It also states 'Fixes nothing,' implying it's for detection rather than remediation. It doesn't explicitly exclude scenarios or name alternative tools, but the context is clear enough for an agent to decide when to invoke it.

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

vc_diffDiff two committed versionsA
Read-only

Unified diff between two committed versions — of one record (resource + id) or the whole repo. Defaults answer "what did the last change change?": ref_b = HEAD, ref_a = the previous commit touching the record (or HEAD's parent repo-wide). Pass hashes from vc_log for any pair. Inspect the diff BEFORE restore_resource so a revert is never blind. Requires PORTAL_VC_DIR.

NameRequiredDescriptionDefault
idNoRecord id (requires resource).
ref_aNoOlder ref/hash (default: the commit before ref_b for this record).
ref_bNoNewer ref/hash (default HEAD).
resourceNoRecord kind to scope to, e.g. 'block' or 'layout' (with id).
max_charsNoCap the diff text (default 40000 chars; the file list is always complete).

Output Schema

NameRequiredDescription
okYes
diffYes
noteNo
ref_aYes
ref_bYes
truncatedYes
files_changedYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already mark readOnlyHint=true, so the description adds value beyond that by explaining the default ref behavior (ref_b=HEAD, ref_a=previous commit) and the requirement for PORTAL_VC_DIR. It also notes that the file list is always complete even when max_chars caps the diff text. No contradictions with annotations.

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?

The description is three sentences, front-loaded with the core purpose, then defaults, then a usage warning and environment requirement. Every sentence earns its place with no redundancy.

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?

Given the output schema exists and annotations are present, the description covers the key behavioral aspects: two scoping modes, default refs, the pre-restore use case, and the PORTAL_VC_DIR dependency. It doesn't enumerate potential errors or return structure, but the output schema handles that, and the description is otherwise complete.

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. The description adds meaning by explaining how ref_a/ref_b defaults are calculated, that passing hashes from vc_log enables arbitrary pairs, and that max_chars caps diff text while the file list remains complete. This enriches the parameter understanding beyond the schema.

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?

The description clearly states the tool produces a unified diff between two committed versions, and distinguishes between scoping to a single record or the whole repo. It is differentiated from sibling tools like vc_status (status) and vc_log (log) by focusing on diffing commits.

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?

The description gives clear context for when to use this tool, specifically advising to inspect the diff BEFORE restore_resource. It also mentions passing hashes from vc_log, implying vc_log is the source for refs. It lacks explicit exclusions or a named alternative for 'when not to use', but the usage guidance is solid.

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

vc_logVersion-control historyA
Read-only

List recent commits, optionally scoped to one record. Use a returned hash with restore_resource to revert to that version. Requires PORTAL_VC_DIR.

NameRequiredDescriptionDefault
idNoRecord id (requires resource).
limitNoMax commits (default 20).
resourceNoRecord kind, e.g. 'block' or 'layout'.

TDQS

A3.8/5.0
Behavior3/5

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

The readOnlyHint=true annotation already declares safety, so the description adds value with the PORTAL_VC_DIR prerequisite and the fact that a returned hash can be used with restore_resource. It does not describe ordering, error behavior, or concurrency, but the annotation lowers the burden and the added requirement is useful context.

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 carry all essential information: what the tool does, optional scoping, integration with restore_resource, and a required environment variable. The most important verb is front-loaded, and there is 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?

For a read-only listing tool with no output schema, the description covers purpose, scoping, a key output usage (hash for restore), and a prerequisite. It leaves ordering and pagination behavior implicit, but the schema documents the limit parameter and the readOnlyHint covers the safety profile.

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?

The input schema covers 100% of the parameters, so the description is not required to explain them. It adds minimal semantic value by saying commits can be "optionally scoped to one record," which loosely maps to id and resource, but this is already implied by the schema descriptions.

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?

The description states a specific verb and resource: "List recent commits", with an optional scope to one record. It also distinguishes from sibling version-control tools like vc_status and vc_diff by focusing on commit history and explicitly linking to restore_resource via the returned hash.

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 gives clear context for when to use the tool, namely to view recent commit history and to obtain a hash for revert via restore_resource. However, it does not explicitly mention when not to use it or name alternatives like vc_status or vc_diff, leaving the comparison to the agent to infer.

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

vc_statusVersion-control statusA
Read-only

Report whether portal version control is enabled (set PORTAL_VC_DIR to a git repo path), the repo location, and push config (PORTAL_VC_PUSH / PORTAL_VC_REMOTE). When enabled, every content write (blocks, layouts, queries, themes, partials, snippets, translations, dashboards, tags) is auto-committed so it can be reverted with restore_resource.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

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

The readOnlyHint annotation already marks it safe, and the description adds useful behavior beyond that: every content write is auto-committed and can be reverted via restore_resource. This alerts the agent to causality and reversibility while remaining consistent with the read-only annotation.

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?

The description delivers a dense but complete picture in two sentences. Every phrase adds value: the enable condition, the reported fields, and the operational consequence of auto-committing. There is no filler.

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 zero-parameter read-only status tool, this description is complete. It tells the agent what will be reported, how version control is enabled, which environment variables matter, and what behavior follows when enabled.

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 has zero parameters and 100% schema coverage, so no parameter explanation is necessary. The description correctly focuses entirely on behavior and return meaning rather than inventing input semantics.

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?

The description uses a specific verb, 'Report', and names precise resources and scope: portal version-control enabled state, repo location, and push configuration. It reads as a clear status command that an agent can distinguish from vc_log, vc_diff, and restore_resource without inspecting those 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?

The description provides clear context: call this tool when you need to know the version-control configuration or understand auto-commit behavior. It does not explicitly name alternative tools or exclude cases, 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. 40 tool updatesv4.4.1
    • First observedbind_block_query
    • First observedchange_password
    • First observedcheck_connection
    • First observedcleanup_scratch
    • First observedconfigure_project
    • First observedcreate_block
    • First observedcreate_resource
    • First observeddelete_resource
    • First observeddescribe_resource
    • First observedexecute_query
    • First observedfind_resource
    • First observedget_capabilities
    • First observedget_config
    • First observedget_metrics
    • First observedget_references
    • First observedget_resource
    • First observedget_rules
    • First observedget_user_access
    • First observedget_version
    • First observedlist_resource
    • First observedmigration_preflight
    • First observednaming
    • First observedplace_blocks
    • First observedprofile_datasource
    • First observedreload_config
    • First observedrepair_query_metadata
    • First observedrestore_resource
    • First observedrun_db_modification
    • First observedscore_portal
    • First observedset_user_access
    • First observedsnapshot_portal
    • First observedsynthesize_theme
    • First observedupdate_block
    • First observedupdate_config
    • First observedupdate_resource
    • First observedvalidate_block
    • First observedvalidate_portal
    • First observedvc_diff
    • First observedvc_log
    • First observedvc_status

TDQS

A4.1/5.0

Scored across 40 tools

Disambiguation4/5

Most tools have clear, distinct purposes targeting specific resources or actions. However, there is some overlap between generic resource CRUD (create_resource, update_resource) and typed block wrappers (create_block, update_block), and a cluster of status/config tools (get_rules, get_config, get_capabilities, get_version, check_connection) that could be confused at a glance.

Naming Consistency4/5

The vast majority follow a consistent verb_noun snake_case pattern (get_, create_, update_, delete_, list_, validate_, execute_, etc.). Minor deviations exist: 'naming' is a bare gerund, 'migration_preflight' is noun_noun without a verb, and the 'vc_*' prefix (vc_status, vc_log, vc_diff) uses a shortened prefix instead of full verbs.

Tool Count2/5

At 40 tools, this server is well beyond the 25-tool threshold where tool sets become heavy and hard for an agent to navigate. While each tool has a specific role, the surface bundles many subdomains (content, queries, users, config, version control, migration) into a single server, making selection more difficult.

Completeness5/5

The generic CRUD tools (create_resource, get_resource, update_resource, delete_resource, list_resource, describe_resource) cover every resource kind, while typed tools handle blocks, queries, datasources, users, config, version control, and auditing. This provides full lifecycle coverage with no obvious dead ends: missing specific operations (e.g., creating a query) can be achieved via the generic resource tools.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    Not graded
    maintenance
    Enables comprehensive PostgreSQL database management through natural language including queries, schema operations, user management, and administrative tasks. Features enterprise-grade connection pooling, transaction support, and full database administration capabilities.
    11
    146 npm
    1
    -
  • A
    license
    A
    quality
    C
    maintenance
    Enables management of LaunchNotes projects and announcements through natural language, including customization of themes, colors, content, and publishing announcements with full read/write access via the LaunchNotes GraphQL API.
    22
    15 npm
    MIT
  • A
    license
    A
    quality
    Not graded
    maintenance
    AI-powered WordPress management that enables creating and editing posts, pages, media, plugins, themes, and Gutenberg blocks through natural language with safe-by-default writes and full rollback support.
    5
    24 npm
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables natural language management of apps, services, resources, attributes, and data via the Dimetrics API with full CRUD operations and advanced filtering.
    -