cityjson-mcp
CityJSON MCP
Un servidor local Model Context Protocol (MCP) para trabajar realmente con CityJSON, en lugar de solo leer la especificación.
Proporciona a clientes MCP como Claude Desktop, Cursor y VS Code una API de herramientas estable orientada a CityJSON respaldada por:
cjio — manipulación de CityJSON, filtrado, operaciones CRS, limpieza, fusión y exportación.
cjval — validación oficial de sintaxis, esquema y estructura de CityJSON/CityJSONSeq.
val3dity — comprobación de validez geométrica 3D para primitivas CityJSON.
citygml-tools — conversión CityGML ↔ CityJSON.
cjdb + PostgreSQL/PostGIS — almacenamiento/importación/exportación persistente de CityJSON.
Especificación CityJSON 2.0.2, JSON Schemas y registro de Extensiones — acceso de referencia canónico en vivo para el agente.
El servidor expone 38 herramientas MCP. Las transformaciones utilizan manejadores de conjuntos de datos inmutables: una operación como cityjson_subset devuelve un nuevo dataset_id y no sobrescribe el conjunto de datos de origen. Un host de chat opcional de una página transmite los adjuntos del navegador a la bandeja de entrada de entrada de MCP y envía solo los manejadores de conjuntos de datos al modelo configurado.
Estado: esta es una implementación práctica v0.1. La imagen Docker recomendada incluye todos los backends externos; el desarrollo sin Docker aún requiere instalar los comandos individuales.
Arquitectura
flowchart LR
CLIENT["MCP clients<br/>Claude Desktop · Cursor · VS Code"]
BROWSER["One-page chat<br/>browser + attachments"]
CHAT["Chat host<br/>model API + MCP client"]
MODEL["Tool-capable model<br/>Anthropic · OpenAI"]
INPUT["Input inbox<br/>streamed CityJSON files"]
SERVER["Docker container<br/>CityJSON MCP · stdio server"]
CORE["Dataset manager<br/>immutable handles + path policy"]
NATIVE["Native inspection/query<br/>JSON + CityObjects + bbox"]
CJIO["cjio<br/>transform · subset · export"]
CJVAL["cjval<br/>schema + structural validation"]
VAL3["val3dity<br/>3D geometry validation"]
CGML["citygml-tools<br/>CityGML ↔ CityJSON"]
CJDB["cjdb + PostGIS<br/>persistence"]
KNOW["CityJSON 2.0.2 references<br/>spec + schemas + extensions"]
CLIENT -->|MCP stdio| SERVER
BROWSER --> CHAT
BROWSER -->|file stream| INPUT
CHAT --> MODEL
CHAT -->|MCP stdio| SERVER
INPUT --> CORE
SERVER --> CORE
CORE --> NATIVE
CORE --> CJIO
CORE --> CJVAL
CORE --> VAL3
CORE --> CGML
CORE --> CJDB
SERVER --> KNOWDescargar PNG — alta resolución
La API orientada a MCP deliberadamente no expone comandos de shell arbitrarios como run_cjio("..."). Cada herramienta MCP tiene un esquema de entrada tipado. Los comandos se invocan con spawn(..., { shell: false }), lo que mantiene estable el contrato orientado al agente y evita la interpolación de cadenas de shell.
Related MCP server: lunar
Flujo de trabajo típico del agente
flowchart TD
START["User asks about a CityJSON file"]
IMPORT["cityjson_import<br/>returns dataset_id"]
INSPECT["Inspect/query<br/>info · list_objects · get_object · query"]
VALIDATE["Validate<br/>cjval + val3dity"]
TRANSFORM["Transform<br/>subset · LoD · CRS · clean · triangulate · merge"]
DERIVED["New immutable dataset_id"]
OUTPUT["Output<br/>save · export · CityGML · cjdb"]
KNOW["Need semantics?<br/>spec · schema · extensions"]
START --> IMPORT
IMPORT --> INSPECT
IMPORT --> VALIDATE
IMPORT --> TRANSFORM
TRANSFORM --> DERIVED
DERIVED --> VALIDATE
DERIVED --> OUTPUT
INSPECT --> OUTPUT
VALIDATE --> OUTPUT
INSPECT --> KNOW
VALIDATE --> KNOWDescargar PNG — alta resolución
Un usuario puede decir, por ejemplo:
Importa
rotterdam.city.json, valida tanto su estructura CityJSON como su geometría 3D, conserva solo los edificios dentro del bbox[90000, 435000, 91000, 436000], reproyecta el resultado a EPSG:28992, limpia los vértices duplicados y huérfanos, valida el resultado nuevamente y devuélvelo concityjson_download.
Un cliente MCP puede resolver esa solicitud aproximadamente como:
cityjson_importcityjson_validatecityjson_subsetcityjson_reprojectcityjson_clean_verticescityjson_validatecityjson_save
Cada transformación devuelve un nuevo dataset_id, por lo que los estados intermedios permanecen disponibles durante la conversación.
Inicio rápido
Chat de una página DATUM con adjuntos directos
La aplicación de chat DATUM incluida es el flujo de trabajo de adjuntos más simple. Transmite cada adjunto del navegador a CITYJSON_MCP_INPUT, lo importa a través del servidor MCP en vivo y le da al modelo solo el dataset_id resultante y un resumen.
Opcionalmente, puede preconfigurar un modelo predeterminado en un archivo de entorno local:
cp .env.example .envSeleccione el estilo de API, luego establezca un ID de modelo con capacidad de herramientas, su clave y su URL base. Por ejemplo, DeepSeek usa el estilo compatible con OpenAI:
MODEL_PROVIDER=openai
MODEL_NAME=deepseek-v4-pro
MODEL_API_KEY=your-api-key
MODEL_BASE_URL=https://api.deepseek.comEste archivo es opcional: el modelo, el proveedor, la clave de API y la URL base también se pueden ingresar en el diálogo Configurar modelo de la aplicación. Las credenciales del diálogo se mantienen solo en la memoria del servidor para la sesión del navegador y nunca se devuelven al navegador ni se pasan a una herramienta MCP.
MODEL_PROVIDER acepta anthropic o openai porque selecciona el protocolo de API, no la empresa que sirve el modelo. anthropic usa Messages; openai usa Chat Completions compatible con OpenAI y, por lo tanto, también admite servicios compatibles como DeepSeek a través de MODEL_BASE_URL.
Ejecute la aplicación completa. Este es el valor predeterminado porque la imagen contiene cjio, cjval, val3dity, citygml-tools y cjdb:
npm install
npm run chatLuego abra http://127.0.0.1:3000. Adjuntar un archivo realiza esta secuencia automáticamente:
browser multipart stream → input inbox → cityjson_import → dataset_id → model tool loopnpm run chat es equivalente a:
docker compose -f docker/docker-compose.chat.yml up --buildLa configuración de Compose vincula la aplicación solo a 127.0.0.1 y mantiene los datos de entrada/espacio de trabajo en volúmenes Docker. Lee un modelo predeterminado opcional de .env; de lo contrario, la aplicación abre el diálogo de configuración del modelo.
Para desarrollo en un host donde los cinco ejecutables ya están instalados, use npm run chat:host. El modo host realiza una verificación de preparación del backend y se niega a anunciar una caja de herramientas no funcional. CHAT_ALLOW_PARTIAL_BACKENDS=true anula esa verificación solo para desarrollo deliberado de solo inspección.
Clientes MCP independientes con el runtime Docker completo
La imagen Docker contiene el servidor MCP y los cinco backends. Instale Docker Desktop, luego extraiga la imagen de Docker Hub:
docker pull yarroudh/cityjson-mcp:latestConfirme que todos los backends estén presentes:
docker run --rm --entrypoint node yarroudh/cityjson-mcp:latest /app/scripts/doctor.mjsLa salida debe informar OK para cjio, cjval, val3dity, citygml-tools y cjdb.
Configurar una bandeja de entrada de entrada
MCP en sí no transfiere adjuntos de chat ordinarios. Para Claude Desktop y otros clientes independientes, monte un directorio host una vez. Reemplace /absolute/path/to/cityjson-files con un directorio absoluto real:
{
"mcpServers": {
"cityjson": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--mount",
"type=bind,source=/absolute/path/to/cityjson-files,target=/input,readonly",
"--env",
"CITYJSON_MCP_ALLOWED_ROOTS=/input:/data",
"--env",
"CITYJSON_MCP_INPUT=/input",
"yarroudh/cityjson-mcp:latest"
]
}
}
}El directorio host aparece como /input dentro de Docker. Los usuarios y agentes se refieren solo al nombre de archivo:
Importa
model.city.jsony resúmelo.
El agente llama a cityjson_import({"filename":"model.city.json"}). cityjson_list_imports puede descubrir nombres de archivo disponibles, y cityjson_import copia la fuente seleccionada al espacio de trabajo administrado inmutable. El montaje de entrada no se puede modificar.
Las rutas de adjuntos de chat como /mnt/user-data/... y /home/claude/... pertenecen al entorno privado del cliente. No existen dentro del contenedor MCP. cityjson_import_text sigue disponible solo para texto JSON pequeño suministrado programáticamente; cityjson_upload es su alias de compatibilidad obsoleto y no es un canal real de carga de archivos.
La imagen incluye cjio, cjval, val3dity, citygml-tools y cjdb; no se requieren bibliotecas Python, Rust, Java o geoespaciales del host. Docker extrae automáticamente capas de imagen más nuevas cuando sea necesario después de ejecutar docker pull yarroudh/cityjson-mcp:latest nuevamente.
Para compilar desde el código fuente, cachee las dos etapas lentas del compilador antes de construir la imagen restante:
npm install
npm run docker:cache:val3dity
npm run docker:cache:cjval
npm run docker:build
npm run docker:doctorSi una capa posterior falla, volver a ejecutar el comando final reutiliza las capas completadas de val3dity y cjval en lugar de compilarlas desde cero.
Opcional: ejecutar sin Docker
Las siguientes secciones solo son necesarias cuando se ejecuta node src/index.mjs directamente en lugar de usar la imagen Docker completa.
1. Requisitos
El servidor MCP en sí necesita:
Node.js 20+
npm
Instale sus dependencias de JavaScript:
cd cityjson-mcp
npm installLuego verifique el código fuente y las pruebas nativas:
npm run check
npm testCompruebe qué backends externos están disponibles:
npm run doctorEl MCP puede iniciarse incluso si faltan algunos backends. Solo fallarán las herramientas que dependen de un backend faltante. El agente también puede llamar a cityjson_backend_status por sí mismo.
2. Instale los backends que necesite
cjio
Proyecto oficial: https://github.com/cityjson/cjio
python -m pip install 'cjio[export,reproject,validate]'Los extras son útiles porque la reproyección, la triangulación/exportación y las operaciones relacionadas necesitan paquetes Python opcionales.
cjval
Proyecto oficial: https://github.com/cityjson/cjval
Instale Rust, luego:
cargo install cjval --features build-binaryval3dity
Proyecto oficial: https://github.com/tudelft3d/val3dity
En macOS, el proyecto upstream proporciona una fórmula Homebrew:
brew tap tudelft3d/software
brew install val3dityEn Windows, use el ejecutable de la versión upstream. En Linux, siga las instrucciones de compilación CMake/CGAL/Eigen/GEOS upstream. val3dity actualmente valida CityJSON/CityJSONSeq directamente; las versiones actuales ya no analizan CityGML, así que use citygml_to_cityjson primero cuando su fuente sea CityGML.
citygml-tools
Proyecto oficial: https://github.com/citygml4j/citygml-tools
Las versiones actuales requieren Java 17+. Descargue y descomprima la distribución, luego asegúrese de que el lanzador citygml-tools esté en PATH, o apunte CITYGML_TOOLS_BIN al lanzador. La versión estable actual en el momento de preparar este README es 2.5.0.
cjdb
Proyecto oficial: https://github.com/cityjson/cjdb
python -m pip install cjdbcjdb requiere PostgreSQL con PostGIS. Se incluye un archivo compose de desarrollo en docker/docker-compose.postgis.yml.
3. Autorice las carpetas a las que el MCP puede acceder
El servidor rechaza rutas de archivo fuera de las raíces autorizadas explícitamente.
Ejemplo macOS/Linux:
export CITYJSON_MCP_ALLOWED_ROOTS="/Users/me/citydata:/Volumes/3d-city-models"
export CITYJSON_MCP_INPUT="/Users/me/citydata/input"
export CITYJSON_MCP_WORKSPACE="/Users/me/citydata/.cityjson-mcp-workspace"Windows usa punto y coma entre raíces:
C:\citydata;D:\city-modelsEl espacio de trabajo almacena conjuntos de datos CityJSON derivados, informes de validación y archivos CityJSONSeq intermedios. Se crea automáticamente.
Anulaciones de ejecutables opcionales:
export CJIO_BIN=/custom/path/cjio
export CJVAL_BIN=/custom/path/cjval
export VAL3DITY_BIN=/custom/path/val3dity
export CITYGML_TOOLS_BIN=/custom/path/citygml-tools
export CJDB_BIN=/custom/path/cjdbPara cjdb, establezca la contraseña de PostgreSQL en el entorno del proceso en lugar de ponerla en los argumentos MCP:
export PGPASSWORD='...'4. Pruebe el servidor manualmente
Los servidores MCP stdio normalmente parecen "no hacer nada" cuando se lanzan directamente porque están esperando mensajes MCP JSON-RPC en stdin. Aún puede confirmar el inicio con:
npm run doctor
npm testLuego configure uno de los clientes MCP a continuación. Las plantillas suministradas lanzan la imagen Docker completa. Los contribuyentes pueden reemplazar el comando Docker con una ruta absoluta a node src/index.mjs y establecer las variables de entorno anteriores.
Añadirlo a Claude Desktop
Las configuraciones MCP locales de Claude Desktop usan un objeto mcpServers. La plantilla suministrada lanza la imagen publicada sin un montaje host. Agregue el montaje que se muestra en el inicio rápido cuando trabaje con archivos grandes.
La plantilla de Claude Desktop está en config/claude-desktop.json.
{
"mcpServers": {
"cityjson": {
"command": "docker",
"args": ["run", "--rm", "-i", "yarroudh/cityjson-mcp:latest"]
}
}
}Las ubicaciones de configuración típicas para servidores locales de Claude Desktop son:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Fusione la plantilla en la configuración del cliente, luego cierre y vuelva a abrir completamente Claude Desktop. El directorio config/ contiene plantillas; Claude no lo lee automáticamente.
En un chat normal de Claude, haga clic en +, abra Connectors, habilite cityjson y permita sus herramientas en Tool access. El conector está disponible solo para chats donde está habilitado. /input existe dentro del contenedor del conector, no dentro del entorno de código de Claude.
Para verificar el uso de herramientas en macOS:
tail -f "$HOME/Library/Logs/Claude/mcp-server-cityjson.log"Las llamadas exitosas aparecen como method="tools/call" seguidas de un resultado del servidor. Presione Ctrl+C para dejar de observar.
Claude Desktop también admite MCP Bundles/Extensions empaquetados. Este repositorio se entrega como ZIP de código fuente para que siga siendo transparente y editable; la configuración stdio directa anterior es la configuración de desarrollo más simple.
Añadirlo a Claude Code
La plantilla de Claude Code está en config/claude-code.json. Cópiela a .mcp.json en el proyecto donde ejecuta Claude Code:
cp config/claude-code.json .mcp.jsonReinicie Claude Code o reconecte sus servidores MCP después de cambiar la configuración.
Añadirlo a Cursor
Cursor admite servidores MCP stdio locales en mcp.json.
Se incluye una plantilla en config/cursor-mcp.json.
Configuración del proyecto:
your-project/
└── .cursor/
└── mcp.jsonConfiguración global:
~/.cursor/mcp.jsonEjemplo:
{
"mcpServers": {
"cityjson": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "yarroudh/cityjson-mcp:latest"]
}
}
}Una vez habilitado, Cursor descubre las herramientas MCP y puede seleccionarlas automáticamente. También puede nombrar explícitamente una herramienta en el mensaje, por ejemplo:
Usa
cityjson_validateen este modelo, luego explica cada error de val3dity que falle usando la especificación CityJSON cuando sea relevante.
Documentación de Cursor: https://cursor.com/docs/mcp
Añadirlo a VS Code
VS Code usa un mcp.json cuya clave de nivel superior es servers.
Se incluye una plantilla en config/vscode-mcp.json.
Configuración del espacio de trabajo:
your-project/
└── .vscode/
└── mcp.jsonEjemplo:
{
"servers": {
"cityjson": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "yarroudh/cityjson-mcp:latest"]
}
}
}Abra la Paleta de comandos y use los comandos de administración del servidor MCP para inspeccionar/iniciar el servidor si es necesario. VS Code también admite controles de sandbox MCP en plataformas compatibles; esos se pueden superponer sobre la propia política de raíces permitidas de este servidor.
Documentación de VS Code: https://code.visualstudio.com/docs/agents/reference/mcp-configuration
Modelo de configuración del cliente
flowchart LR
CLAUDE["Claude Desktop<br/>claude_desktop_config.json"]
CLAUDECODE["Claude Code<br/>.mcp.json"]
CURSOR["Cursor<br/>.cursor/mcp.json"]
VSCODE["VS Code<br/>.vscode/mcp.json"]
WEB["CityJSON chat<br/>browser"]
HOST["Chat host<br/>model + MCP client"]
DOCKER["CityJSON MCP Docker image<br/>MCP stdio"]
INPUT["Input inbox<br/>/input"]
WS["Managed workspace<br/>/data"]
TOOLS["Bundled backends<br/>cjio · cjval · val3dity · citygml-tools · cjdb"]
CLAUDE --> DOCKER
CLAUDECODE --> DOCKER
CURSOR --> DOCKER
VSCODE --> DOCKER
WEB -->|stream attachments| INPUT
WEB --> HOST
HOST --> DOCKER
INPUT --> DOCKER
DOCKER --> WS
DOCKER --> TOOLSDescargar PNG — alta resolución
Catálogo de herramientas
Conjunto de datos y diagnósticos
Tool | Backend | Propósito | Entradas clave |
| nativo | Informa si | ninguna |
| nativo | Lista los nombres de archivos JSON disponibles en la bandeja de entrada configurada. | ninguna |
| nativo | Importa un archivo de la bandeja de entrada por nombre y devuelve un |
|
| nativo | Alternativa de texto corto para clientes programáticos; el contenido viaja a través del JSON de MCP. |
|
| nativo | Abre un archivo JSON CityJSON normal y devuelve un |
|
| nativo | Alias de compatibilidad obsoleto de |
|
| nativo | Prepara un modelo abierto o transformado para su transmisión web directa o una descarga MCP integrada. |
|
| nativo | Resume tipo/versión, recuentos de objetos, LoDs, atributos, metadatos, transformación y extensiones. |
|
| nativo | Copia un conjunto de datos abierto/derivado a una ruta autorizada explícita. |
|
cityjson_import
Úselo para archivos entregados a la bandeja de entrada por la aplicación de chat o colocados en un directorio montado:
{
"filename": "amsterdam.city.json"
}Si se desconoce el nombre del archivo, llame a cityjson_list_imports. Omitir filename importa automáticamente solo cuando hay exactamente un archivo JSON presente. La herramienta copia y valida el origen antes de devolver un identificador.
cityjson_import_text
Úselo solo cuando un documento CityJSON pequeño ya exista como texto en un flujo de trabajo de aplicación:
{
"filename": "model.city.json",
"content": "{\"type\":\"CityJSON\",\"version\":\"2.0\",\"CityObjects\":{},\"vertices\":[]}"
}El contenido se verifica estructuralmente antes de escribirse en el espacio de trabajo gestionado. No es apropiado para adjuntos de navegador/chat porque el documento completo viaja a través de la solicitud MCP. cityjson_upload se conserva como un alias obsoleto por compatibilidad.
cityjson_open
cityjson_open sigue disponible para clientes avanzados que proporcionan intencionadamente una ruta completa visible por el servidor dentro de una raíz permitida. Los flujos de trabajo normales de bandeja de entrada y adjuntos deben usar cityjson_import.
cityjson_download
Úselo para recuperar un conjunto de datos de origen o transformado cuando el contenedor no tiene montado un directorio del host:
{
"dataset_id": "cj_abc123def456",
"filename": "cleaned.city.json"
}En DATUM, el host transmite directamente el archivo inmutable del espacio de trabajo y presenta un botón de descarga, por lo que los resultados grandes no pasan por el contexto del modelo ni por el JSON de MCP. Los clientes MCP independientes reciben un recurso application/json integrado; esa ruta integrada tiene un límite predeterminado de 25 MiB controlado por CITYJSON_MCP_MAX_DOWNLOAD_BYTES.
Resultado representativo:
{
"datasetId": "cj_4ad572e79331",
"version": "2.0",
"cityObjectCount": 12543,
"vertexCount": 382901,
"lods": ["1.2", "2.2"]
}El identificador son metadatos en memoria que apuntan a un archivo; el documento CityJSON en sí no se copia simplemente al abrirlo.
Inspección y consulta
Tool | Backend | Propósito | Entradas clave |
| nativo | Lista paginada de CityObjects con ID, tipo, atributos, LoDs y relaciones. |
|
| nativo | Devuelve un CityObject completo y calcula su bbox 3D a partir de los vértices referenciados. |
|
| nativo | Filtra por IDs, tipos de CityObject, bbox 2D y predicados de atributos. |
|
cityjson_query es la forma preferida de permitir que un LLM inspeccione modelos grandes sin enviar el documento CityJSON completo al contexto del modelo.
Ejemplo:
{
"dataset_id": "cj_4ad572e79331",
"types": ["Building", "BuildingPart"],
"bbox": [85000, 446000, 86000, 447000],
"attributes": {
"yearOfConstruction": { "gte": 2000 },
"status": { "in": ["existing", "planned"] }
},
"limit": 100
}Operadores de predicado de atributos:
eqneqgtgteltltecontainsin
El filtro de bbox es [minX, minY, maxX, maxY] en el CRS del conjunto de datos. Los cuadros delimitadores de objetos se calculan a partir de los vértices referenciados del objeto y de la transform de CityJSON cuando está presente.
Validación
flowchart LR
DATA["Opened CityJSON<br/>dataset_id"]
ALL["cityjson_validate"]
CJVAL["cityjson_validate_schema<br/>cjval"]
VAL3["cityjson_validate_geometry<br/>val3dity"]
STRUCT["JSON + schema + structural<br/>consistency result"]
GEOM["ISO 19107-style 3D<br/>geometry report"]
COMBINE["Combined validation result"]
DATA --> ALL
ALL --> CJVAL
ALL --> VAL3
CJVAL --> STRUCT
VAL3 --> GEOM
STRUCT --> COMBINE
GEOM --> COMBINEDescargar PNG — alta resolución
Tool | Backend | Propósito | Entradas clave |
| cjval | Validación oficial de sintaxis/esquema y coherencia estructural de CityJSON. |
|
| val3dity | Valida las primitivas 3D admitidas y devuelve el informe JSON de val3dity. |
|
| cjval + val3dity | Ejecuta ambos validadores simultáneamente y devuelve un resultado combinado. |
|
Cuándo usar cada validador
Use cityjson_validate_schema para preguntas como:
¿Es el JSON CityJSON sintácticamente válido?
¿Se ajusta al esquema de CityJSON?
¿Son coherentes las referencias padre/hijo?
¿Existen los índices de vértices?
¿Son estructuralmente coherentes las matrices de semántica/materiales/texturas?
¿Son válidos los esquemas de extensión?
Use cityjson_validate_geometry para la validez geométrica de las primitivas MultiSurface, CompositeSurface, Solid, MultiSolid y CompositeSolid y las comprobaciones geométricas específicas de CityJSON relacionadas.
Para la solicitud habitual del usuario «validar este CityJSON», use cityjson_validate.
Ejemplo:
{
"dataset_id": "cj_4ad572e79331"
}Si una advertencia de cjval informa de vértices duplicados o sin usar, un bucle de reparación natural es:
cityjson_clean_verticescityjson_validate_schemaopcionalmente
cityjson_validate_geometry
Transformación y manipulación
Todas las herramientas de esta sección devuelven un nuevo identificador de conjunto de datos.
Tool | Backend | Propósito | Entradas importantes |
| cjio | Seleccionar/excluir CityObjects por IDs, bbox, radio, recuento aleatorio y/o tipos de CityObject. |
|
| cjio | Conservar un LoD. |
|
| cjio | Transformar coordenadas a un CRS EPSG de destino. |
|
| cjio | Asignar una referencia EPSG sin cambiar las coordenadas. |
|
| cjio | Trasladar el origen de coordenadas, opcionalmente usando XYZ mínimos explícitos. |
|
| cjio | Eliminar vértices duplicados y huérfanos. |
|
| cjio | Triangular superficies. |
|
| cjio | Fusionar dos o más conjuntos de datos abiertos. |
|
| cjio | Renombrar un atributo de CityObject en todo el modelo. |
|
| cjio | Eliminar un atributo de todos los CityObjects. |
|
| cjio | Eliminar información de texturas. |
|
| cjio | Eliminar información de materiales. |
|
| cjio | Actualizar una versión anterior de CityJSON compatible con el cjio instalado. |
|
Ejemplos de subconjuntos
Edificios en un bbox:
{
"dataset_id": "cj_4ad572e79331",
"types": ["Building"],
"bbox": [85000, 446000, 86000, 447000]
}Objetos específicos:
{
"dataset_id": "cj_4ad572e79331",
"ids": ["NL.IMBAG.Pand.001", "NL.IMBAG.Pand.002"]
}Todo excepto los objetos de vegetación:
{
"dataset_id": "cj_4ad572e79331",
"types": ["SolitaryVegetationObject", "PlantCover"],
"exclude": true
}Gestión de CRS
Use cityjson_assign_crs solo cuando las coordenadas ya estén expresadas en el CRS y los metadatos falten o sean incorrectos. No transforma coordenadas.
Use cityjson_reproject cuando las coordenadas deban transformarse realmente:
{
"dataset_id": "cj_4ad572e79331",
"epsg": 28992
}Para una reproyección fiable, el modelo de origen necesita un CRS de origen utilizable.
Exportación e interoperabilidad
Tool | Backend | Propósito | Entradas |
| cjio | Exportar a CityJSONSeq/JSONL, OBJ, STL, GLB o B3DM. |
|
| citygml-tools | Convertir GML/XML de CityGML a CityJSON o CityJSONSeq; la salida CityJSON normal se abre automáticamente. |
|
| citygml-tools | Convertir un modelo CityJSON abierto a CityGML. |
|
Ejemplo de exportación:
{
"dataset_id": "cj_4ad572e79331",
"format": "glb",
"destination": "/data/buildings.glb"
}Ejemplo de CityGML → CityJSON:
{
"source": "/input/model.gml",
"json_lines": false
}Ejemplo de CityJSON → CityGML:
{
"dataset_id": "cj_4ad572e79331",
"crs_name": "urn:ogc:def:crs:EPSG::28992",
"output_directory": "/data/citygml-output"
}El envoltorio no inventa intencionadamente una opción de versión de destino CityGML/CityJSON. citygml-tools admite CityGML 1.0/2.0/3.0 y CityJSON 1.0/1.1/2.0, pero el comportamiento exacto de la opción de versión de destino en la CLI puede variar según la versión ascendente; los valores predeterminados del backend instalado siguen siendo la autoridad.
Herramientas de base de datos
Herramienta | Backend | Propósito | Entradas |
| cjio + cjdb + PostGIS | Convierte CityJSON normal a CityJSONSeq y luego lo importa en un esquema PostgreSQL/PostGIS. |
|
| cjdb + cjio | Exporta un esquema cjdb completo o un conjunto seleccionado de ID de objetos a CityJSONSeq; opcionalmente lo agrupa en un |
|
Objeto de conexión:
{
"host": "localhost",
"user": "cityjson",
"database": "cityjson",
"schema": "rotterdam"
}Importación:
{
"dataset_id": "cj_4ad572e79331",
"connection": {
"host": "localhost",
"user": "cityjson",
"database": "cityjson",
"schema": "rotterdam"
},
"attribute_indexes": ["yearOfConstruction"],
"partial_attribute_indexes": ["function"]
}Exportación de subconjunto:
{
"connection": {
"host": "localhost",
"user": "cityjson_reader",
"database": "cityjson",
"schema": "rotterdam"
},
"query": "SELECT object_id FROM rotterdam.cj_object WHERE object_id LIKE 'NL.IMBAG.%'",
"collect": true
}El envoltorio rechaza SQL que no sea SELECT, puntos y comas y palabras clave modificadoras evidentes. Esto es una salvaguarda, no un límite de seguridad SQL: use un rol de base de datos con solo los permisos adecuados para la operación. Para exportaciones, use un rol que no pueda modificar datos.
Conocimiento de especificación, esquema y extensiones
Herramienta | Fuente | Propósito |
| índice incluido | Devuelve metadatos de referencia actuales, esquema de capítulos y nombres de esquema conocidos sin acceso a la red. |
| especificación canónica de CityJSON | Obtiene el texto de la especificación CityJSON 2.0.2; puede devolver contexto alrededor de una consulta. |
| punto final canónico de esquema CityJSON de TU Delft | Obtiene un esquema JSON CityJSON 2.0.2 con nombre como JSON analizado. |
| registro oficial | Recupera el registro, opcionalmente alrededor de un término de búsqueda. |
| URL canónica de extensiones CityJSON | Obtiene un esquema de extensión registrado específico por nombre/versión. |
Ejemplo de consulta de especificación:
{
"query": "Geometry templates",
"max_chars": 20000
}Ejemplo de consulta de esquema principal:
{
"name": "geomprimitives.schema.json"
}Ejemplo de descubrimiento de extensiones:
{
"query": "noise"
}Luego obtenga un esquema específico:
{
"name": "noise",
"version": "2.0.0"
}Por qué esto no depende de cityjson/cj-mcp
cityjson/cj-mcp es útil para la recuperación de capítulos de especificación. Este servidor necesita operaciones más amplias, por lo que el adaptador de conocimiento lee las fuentes canónicas de especificación/esquema/extensión de CityJSON directamente e incluye un pequeño índice de referencia 2.0.2 determinista. Esto evita un segundo proceso MCP y un modo de fallo por desincronización de versiones.
Un adaptador futuro podría delegar cityjson_spec_read a cj-mcp sin cambiar los nombres públicos de las herramientas MCP.
Prompts/recetas recomendados
Estos prompts asumen que el directorio de archivos del host está configurado como la bandeja de entrada. El agente usa nombres de archivo y nunca comprueba /input en su propio entorno de código.
Inspeccionar antes de modificar
Importa
tile.city.jsonconcityjson_import. Dime la versión de CityJSON, el CRS, los recuentos de CityObject por tipo, los LoD, los nombres de atributos y las extensiones. No modifiques nada.
Herramientas esperadas: cityjson_import → cityjson_info.
Validar y diagnosticar
Importa
tile.city.jsony luego valídalo concjvalyval3dity. Usa solo las herramientas del conector CityJSON. Separa las advertencias de cjval de los errores, agrupa los errores de val3dity por código de error, identifica los ID de CityObject afectados y consulta la especificación CityJSON cuando un error trate sobre una regla estructural de CityJSON. Si un informe de validación supera el límite de salida de la herramienta, crea subconjuntos espaciales no superpuestos, valida cada subconjunto y agrega los recuentos sin contarlos dos veces. No modifiques el archivo original.
Herramientas esperadas: cityjson_import → cityjson_validate → opcionalmente cityjson_get_object / cityjson_spec_read.
Bucle de limpieza seguro
Importa
tile.city.json, ejecuta la validación estructural y, si las únicas advertencias estructurales son vértices duplicados o sin usar, crea un conjunto de datos derivado limpio, ejecuta la validación completa de nuevo y devuelve el resultado concityjson_downloadcomotile-clean.city.json. Nunca sobrescribas el original.
Herramientas esperadas: cityjson_import → cityjson_validate_schema → cityjson_clean_vertices → cityjson_validate → cityjson_save.
Extracción espacial
Del archivo de la bandeja de entrada
city.city.json, extrae solo los objetos Building y BuildingPart que intersequen el bbox[85000, 446000, 86000, 447000], conserva el LoD 2.2, reproyecta a EPSG:28992, valida el resultado y luego devuélvelo concityjson_downloadcomoextract.city.json.
Herramientas esperadas: cityjson_import → cityjson_subset → cityjson_filter_lod → cityjson_reproject → cityjson_validate → cityjson_save.
Interoperabilidad con CityGML
Convierte
/input/source.gmla CityJSON, inspecciona los tipos de objetos y LoD resultantes, valídalo con cjval y val3dity, e informa de cualquier información que pueda haberse perdido o normalizado durante la conversión.
Herramientas esperadas: citygml_to_cityjson → cityjson_info → cityjson_validate, más consulta de especificación cuando sea útil.
Flujo de trabajo con base de datos
Importa el archivo de la bandeja de entrada
municipality.city.json, valídalo y luego impórtalo en el host PostgreSQLlocalhost, base de datoscityjson, esquemamunicipality. Añade un índice de atributos parayearOfConstruction. Usa la contraseña de la base de datos del entorno del proceso MCP.
Herramientas esperadas: cityjson_import → cityjson_validate_schema → cityjson_db_import.
Razonamiento consciente de extensiones
Este modelo declara la extensión CityJSON
noise. Encuentra la documentación/esquema de la extensión registrada, explica las propiedades adicionales que permite y valida el modelo con su esquema de extensión local si me proporcionas uno.
Herramientas esperadas: cityjson_info → cityjson_extensions_registry → cityjson_extension_schema → opcionalmente cityjson_validate_schema.
Ciclo de vida de los datos e inmutabilidad
El diseño clave es:
browser attachment ──stream──> input inbox ──cityjson_import──> cj_A
mounted inbox file ──────────────────────────cityjson_import──> cj_A
authorized path ─────────────────────────────cityjson_open────> cj_A
│
├── subset ───────> cj_B
│ │
│ └── reproject ──> cj_C
│
└── validate (does not modify data)cityjson_importcopia un archivo de la bandeja de entrada al espacio de trabajo gestionado, lo valida y devuelve el ID de conjunto de datos inicial.cityjson_openregistra una ruta visible por el servidor explícitamente autorizada para flujos de trabajo avanzados.cityjson_import_textes un recurso alternativo para documentos pequeños; su alias obsoletocityjson_uploadno gestiona adjuntos binarios.Una transformación pide al backend que escriba un archivo nuevo dentro de
CITYJSON_MCP_WORKSPACE.El servidor abre el archivo producido y le asigna un nuevo
dataset_idaleatorio.cityjson_savees el paso explícito que copia un estado elegido a un destino seleccionado por el usuario.
Esto facilita mucho que un agente compare la validación antes/después y evita que las llamadas de transformación normales sobrescriban silenciosamente la fuente original.
Modelo de seguridad
Este servidor ejecuta programas geoespaciales potentes localmente. Trata la instalación del servidor MCP como una instalación de código local.
Salvaguardas integradas:
Raíces permitidas — las operaciones de rutas del host deben estar dentro de
CITYJSON_MCP_ALLOWED_ROOTS,CITYJSON_MCP_INPUTo el espacio de trabajo gestionado. Las subidas desde el navegador reciben nombres de archivo aleatorios y seguros dentro del directorio de entrada.Sin herramienta de shell arbitraria — no hay comando
run_shellni herramienta MCPrun_cjiosin restricciones.Sin interpolación de shell — los programas externos se invocan con matrices de argumentos y
shell: false.Esquemas de herramientas tipados — Zod restringe tipos, enumeraciones, enteros EPSG, formas de bbox, identificadores de esquema de base de datos, etc.
La contraseña de PostgreSQL permanece en el entorno — los esquemas de herramientas de base de datos no contienen un campo de contraseña.
Salvaguarda SQL de exportación de BD — solo se aceptan cadenas
SELECTúnicas sin puntos y comas ni palabras clave mutadoras evidentes. Aun así, usa un rol de base de datos con solo los permisos necesarios.Tiempo de espera/límite de salida de comandos — los subprocesos tienen por defecto un tiempo de espera de 120 segundos y una salida capturada limitada. Establece
CITYJSON_MCP_COMMAND_TIMEOUT_MSpara trabajos grandes.
Para entornos compartidos o de producción, ejecuta el MCP bajo una cuenta/contenedor del sistema operativo con solo los permisos de sistema de archivos y base de datos que realmente necesite.
Docker
El docker/Dockerfile incluido instala:
Entorno de ejecución de Node + dependencias de paquetes MCP
cjiocjdbcjvalval3ditycitygml-tools
La mayoría de los usuarios deberían extraer la imagen publicada:
docker pull yarroudh/cityjson-mcp:latestPara una compilación local desde el código fuente, almacena en caché las dos etapas de compilación costosas antes de compilar el resto:
docker build -f docker/Dockerfile --target val3dity-builder -t cityjson-mcp-val3dity-builder .
docker build -f docker/Dockerfile --target cjval-builder -t cityjson-mcp-cjval-builder .
docker build -f docker/Dockerfile -t cityjson-mcp .Ejecuta docker run --rm --entrypoint node cityjson-mcp /app/scripts/doctor.mjs después de una compilación local para verificar los cinco ejecutables.
Publicar desde GitHub Actions
El flujo de trabajo en .github/workflows/docker-publish.yml compila imágenes linux/amd64 y linux/arm64 en ejecutores nativos, crea un manifiesto multiplataforma y lo envía a yarroudh/cityjson-mcp.
Configura el repositorio de GitHub en Settings → Secrets and variables → Actions:
Variable
DOCKERHUB_USERNAME:yarroudhSecreto
DOCKERHUB_TOKEN: un token de acceso de Docker Hub con permiso para escribir en este repositorio
Ejecuta el flujo de trabajo manualmente desde la pestaña Actions, o publica una etiqueta de versión:
git tag v0.1.0
git push origin v0.1.0Una etiqueta de versión publica 0.1.0, 0.1 y latest. La caché de BuildKit se conserva para ejecuciones posteriores, por lo que las capas sin cambios de val3dity y cjval no necesitan compilarse de nuevo.
PostGIS de desarrollo:
docker compose -f docker/docker-compose.postgis.yml up -dConsulta docker/README.md.
Estructura de desarrollo
cityjson-mcp/
├── src/
│ ├── index.mjs # MCP server entry point
│ ├── core/
│ │ ├── dataset-manager.mjs # immutable dataset handles
│ │ ├── cityjson-native.mjs # parsing, summaries, bbox, queries
│ │ ├── path-policy.mjs # allowed filesystem roots
│ │ └── command-runner.mjs # safe subprocess execution
│ ├── adapters/
│ │ ├── cjio.mjs
│ │ ├── cjval.mjs
│ │ ├── val3dity.mjs
│ │ ├── citygml-tools.mjs
│ │ ├── cjdb.mjs
│ │ └── knowledge.mjs
│ ├── tools/
│ │ └── register-tools.mjs
│ └── util/
├── resources/spec/ # deterministic CityJSON 2.0.2 reference index
├── config/ # Claude/Cursor/VS Code examples
├── diagrams/ # Mermaid source + high-resolution PNG exports
├── examples/
├── scripts/
├── test/
└── docker/La capa de protocolo MCP usa la línea estable v2 del SDK oficial de TypeScript del servidor Model Context Protocol y transporte stdio.
Diagramas
Todo el código fuente de Mermaid se almacena en diagrams/*.mmd. Los archivos PNG incluidos se generan a partir de las mismas definiciones de grafo con salida de Graphviz a 300 DPI, con dimensiones en el rango de varios miles de píxeles para que sigan siendo nítidos en documentos/diapositivas.
Regenéralos:
python3 scripts/render_diagrams.pyEl renderizador admite el subconjunto de diagramas de flujo de Mermaid usado en este README y requiere el ejecutable dot de Graphviz.
Archivos PNG actuales:
Pruebas
Las pruebas nativas no necesitan ningún backend geoespacial externo:
npm testPrueban:
Análisis de CityJSON y generación de resúmenes
cálculo de bbox de objetos transformados/descuantificados
consultas nativas de tipo/bbox/atributos
JSON de ejemplo incluido
Comprueba la sintaxis de cada archivo fuente .mjs:
npm run checkLos adaptadores externos son envoltorios deliberadamente finos alrededor de sus CLI oficiales. Para un entorno de despliegue, añade pruebas de integración fijadas a las versiones exactas de backend que despliegues.
Limitaciones conocidas / decisiones de v0.1
cityjson_opennativamente carga un archivo JSON CityJSON normal en memoria. Para flujos CityJSONSeq extremadamente grandes, use flujos de trabajo de backend o añada un adaptador de streaming.Los identificadores de dataset existen durante la vida útil del proceso del servidor MCP; reiniciar el cliente/servidor invalida los valores antiguos de
dataset_id. Vuelva a abrir los archivos de origen/guardados después de reiniciar.Los archivos de espacio de trabajo derivados no se eliminan automáticamente. Esto es intencional para la trazabilidad, pero limpie el espacio de trabajo periódicamente.
cityjson_querycalcula los bboxes a partir de la geometría almacenada explícitamente en cada CityObject. No une automáticamente toda la geometría secundaria en el bbox de un elemento padre.cityjson_spec_read,cityjson_schema_ready las herramientas de registro/esquema de extensiones necesitan acceso de red saliente a los endpoints canónicos de CityJSON.cityjson_spec_outlinefunciona con el índice incluido.cityjson_to_citygmldeja deliberadamente la selección de la versión de CityGML de destino a los valores predeterminados decitygml-toolsinstalado, en lugar de depender de una marca de CLI no verificada.val3dityes software GPL-3.0; este proyecto invoca el ejecutable como backend externo y no lo incluye. Revise las implicaciones de licencia para su propio modelo de distribución/implementación.La imagen base de Docker suministrada no incluye val3dity ni citygml-tools.
Referencias upstream
Especificación CityJSON: https://www.cityjson.org/specs/
Repositorio de la especificación CityJSON: https://github.com/cityjson/specs
Registro de extensiones CityJSON: https://github.com/cityjson/extensions
val3dity: https://github.com/tudelft3d/val3dity
citygml-tools: https://github.com/citygml4j/citygml-tools
MCP CityJSON existente solo de especificación: https://github.com/cityjson/cj-mcp
SDK TypeScript de MCP: https://github.com/modelcontextprotocol/typescript-sdk
Documentación de MCP de Cursor: https://cursor.com/docs/mcp
Documentación de MCP de VS Code: https://code.visualstudio.com/docs/agents/reference/mcp-configuration
Licencia
El código de este repositorio se proporciona bajo la Licencia MIT; consulte LICENSE.
Los backends externos siguen siendo software independiente bajo sus propias licencias. En particular, val3dity es GPL-3.0, citygml-tools es Apache-2.0, y cjio/cjval/cjdb tienen sus propios archivos de licencia upstream. Nada en este repositorio vuelve a licenciar esos proyectos.
Available Tools
42 toolscitygml_to_cityjsonConvert CityGML to CityJSONB
Convert a CityGML 1.0/2.0/3.0 GML/XML file to CityJSON using citygml-tools. A regular CityJSON output is automatically registered and returned by filename.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | ||
| json_lines | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose a meaningful side effect: the output is 'automatically registered and returned by filename,' which tells the agent a backend record is created and what the return value is. It says nothing about write locations, overwrite behavior, or failure modes for unsupported/invalid GML.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the conversion scope front-loaded; 'using citygml-tools' is a minor implementation detail but justifies the version list. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with zero schema coverage, no output schema, and a second boolean parameter, the description leaves too much unspecified — notably the meaning of 'source' and the effect of 'json_lines.' It covers the happy path and the registration side effect but not enough for confident invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it largely does not. It never explains whether 'source' is a filesystem path, an uploaded file id, or a registered name, and it omits the 'json_lines' flag entirely, leaving the agent to guess that it produces CityJSONSeq-style output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Convert a CityGML 1.0/2.0/3.0 GML/XML file to CityJSON'), including the supported input versions, so the direction of conversion is unambiguous and clearly the mirror of cityjson_to_citygml. It does not explicitly name the reverse sibling, but the conversion direction alone is enough to distinguish it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent infers it should call this when it holds a CityGML file. There is no explicit when-to-use, no statement of when NOT to use it, and no differentiation from nearby tools such as cityjson_import or cityjson_import_text that could plausibly also take external data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_assign_crsAssign CityJSON CRSA
Assign/update the EPSG reference without changing coordinate values using cjio. Returns a new filename.
| Name | Required | Description | Default |
|---|---|---|---|
| epsg | Yes | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose two non-obvious behaviors: coordinates are untouched (metadata-only change) and the result is a new filename rather than an in-place mutation of dataset_id. It says nothing about whether the source dataset survives, what happens with an invalid EPSG code, or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler; the key constraint (no coordinate change) and the return value are both front-loaded and immediately scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with no output schema, the description covers the essential contract: it mutates CRS metadata only and returns a new filename. Only error/mutation-safety details are missing, which is a minor gap at this complexity level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: dataset_id is documented in the schema, but epsg only has numeric bounds. The description adds that epsg is an EPSG reference applied to the dataset metadata, which partially compensates, but it does not establish expected format (e.g. 7415 vs 'EPSG:7415') or validity constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (assign/update) and resource (the EPSG reference in the dataset), and the clause 'without changing coordinate values' effectively separates it from cityjson_reproject, which does alter coordinates. It stops short of naming the sibling explicitly, so the differentiation is implied rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'without changing coordinate values' phrasing implies when this is preferred over a reprojection, but there is no explicit 'use this instead of cityjson_reproject when...' guidance, nor any stated preconditions such as requiring an opened dataset.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_attribute_removeRemove CityJSON attributeC
Remove an attribute across CityObjects with cjio.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden and mostly drops it. It implies an irreversible mutation but never says whether the change is applied in place or returns a new dataset, what happens if the attribute is missing on some CityObjects, or whether the result needs cityjson_save to persist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler, and the target scope is stated before the tooling reference. It is arguably too terse for a mutation, but nothing in it is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation with no annotations and no output schema, the description should explain persistence, failure behavior, and the relationship to the sibling rename/remove tools. None of that is present, so an agent would have to guess about side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: dataset_id is documented in the schema, while name has no description at all. The phrase "an attribute" indirectly tells the agent that name is the attribute key, which adds a little meaning, but it does not cover case sensitivity, namespaced/generic attributes, or nested paths.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb-and-resource pair ("Remove an attribute") plus the scope ("across CityObjects") and the underlying engine (cjio). An agent can infer it is the inverse of cityjson_attribute_rename, though the description never names that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus cityjson_attribute_rename or cityjson_query, no stated prerequisites (e.g. the dataset must be opened first), and no exclusions. Usage must be inferred entirely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_attribute_renameRename CityJSON attributeC
Rename an attribute across CityObjects with cjio.
| Name | Required | Description | Default |
|---|---|---|---|
| new_name | Yes | ||
| old_name | Yes | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description bears the full behavioral burden, yet it only implies a mutation via the word "rename." It does not say whether existing attributes on all objects are modified in place, what happens if old_name is absent, whether the change is persisted or in-memory only, or how errors are surfaced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler or repetition. It is efficient, though the brevity is partly under-specification rather than disciplined editing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterized mutation tool with no annotations, no output schema, and undocumented parameters, the definition is too thin. An agent lacks enough to know whether the rename persists, whether a save step is required, and how failures on missing attributes behave.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33% – just dataset_id is documented in the schema, and that text largely references other tools. The description adds nothing about old_name/new_name semantics: no statement on nested or dotted attribute paths, case sensitivity, or whether collisions with an existing new_name are rejected.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Rename an attribute across CityObjects with cjio" gives a specific verb (rename), resource (attribute), scope (across CityObjects) and engine (cjio). It is clear enough to distinguish from cityjson_attribute_remove by name, but the description itself does no explicit sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance: nothing says this is a mutation on an already-opened dataset, whether the change must be followed by cityjson_save or cityjson_export, or when to prefer it over cityjson_attribute_remove or a query-based workflow. The agent must infer all preconditions from the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_backend_statusCityJSON backend statusA
Check which external CityJSON/CityGML engines are installed and callable. Run this first when a backend-dependent operation fails.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of explaining behavior. It states that the tool checks installation and callability, which is useful, but it does not disclose output format, possible side effects, or whether external processes are invoked. This is acceptable for a simple status check but not fully transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, purposeful sentences with no wasted words. The key action is front-loaded and the usage recommendation follows naturally.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter diagnostic tool, the description covers what the tool does and when to run it. It does not specify the return value format, but the intent is clear enough; a brief note on output would make it fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is nothing for the description to add about parameter meaning. The baseline of 4 applies because no parameter documentation burden exists.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Check') and names a specific resource ('external CityJSON/CityGML engines installed and callable'), clearly distinguishing this diagnostic tool from the many file-operation siblings. It also frames the tool's role relative to backend-dependent failures.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent when to run this tool: 'Run this first when a backend-dependent operation fails.' It does not mention exclusions or alternatives, but there are no obvious status-check siblings, so the guidance is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_clean_verticesClean CityJSON verticesB
Remove duplicate and orphan vertices with cjio vertices_clean. Returns a new filename.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose one important behavioral fact: the operation returns a new filename rather than modifying in place, so it is effectively non-destructive. However, it says nothing about whether the original dataset is discarded, whether the new dataset must be saved/exported separately, or what the return string looks like beyond 'a filename'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action and ending with the return value. Nothing is padded, though the mention of the internal cjio command is mild implementation detail rather than agent-facing guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, no-annotation, no-output-schema tool this is close to adequate, and the return value is stated. Still missing is pipeline context: whether the result replaces the input handle, and whether the agent should chain into cityjson_save or cityjson_export afterwards.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single dataset_id parameter is already documented in the schema as coming from cityjson_open, cityjson_import, or a transformation. The description adds no further meaning about accepted handle formats or constraints, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (remove duplicate and orphan vertices) and names the underlying operation (cjio vertices_clean). It is clearly distinguishable from siblings like cityjson_remove_textures or cityjson_validate, though it does not explicitly contrast itself with any of them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no preconditions (e.g. run after import/merge, before export), and no statement about how it relates to validate or triangulate. The agent must infer the workflow position entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_db_exportExport CityJSON from cjdbA
Export all objects or a read-only SELECT-defined subset from cjdb to CityJSONSeq and optionally collect it into a named CityJSON file.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Optional SELECT query that returns object_id rows. Mutating SQL and semicolons are rejected. | |
| collect | No | ||
| connection | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does disclose the read-only restriction (SELECT-defined subset) and the two-stage output shape (CityJSONSeq, then optionally a single CityJSON file). It does not state where files are written, how the output file is named, or what permissions the connection needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence that front-loads the verb and scope, with the optional behavior trailing. No filler, though the 'named CityJSON file' clause introduces ambiguity rather than clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter tool with a self-describing connection object and no output schema, the description covers input modes and output format adequately. The notable gap is the unspecified output file naming/location, which matters for a tool that produces files.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 33%: only 'query' is documented in the schema, and the description reinforces it as a SELECT-defined subset. It also hints that 'collect' controls consolidation into a CityJSON file, but never explains where the 'named' file's name comes from, leaving the boolean's effect only partially specified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Export) and resource (cjdb objects) with an explicit output format (CityJSONSeq) and an optional post-step (collect into a CityJSON file). The 'from cjdb' phrasing distinguishes it from the file-oriented cityjson_export sibling, though no sibling is named outright.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'all objects or a read-only SELECT-defined subset' phrasing implies the choice between omitting and supplying the query parameter, which is useful context. However, it gives no guidance on when to prefer this over cityjson_export, cityjson_query, or cityjson_subset, and no prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_db_importImport CityJSON into cjdbB
Convert the dataset to CityJSONSeq with cjio and import it into PostgreSQL/PostGIS using cjdb. PostgreSQL password should be supplied through PGPASSWORD, not tool arguments.
| Name | Required | Description | Default |
|---|---|---|---|
| connection | Yes | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. | |
| attribute_indexes | No | ||
| partial_attribute_indexes | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With zero annotations the description carries the full burden, and it does disclose the real pipeline (cjio conversion to CityJSONSeq before cjdb ingest) plus an authentication requirement: the password must come from the PGPASSWORD environment variable rather than arguments. It says nothing about what tables/rows are created, whether existing data is overwritten, or how failures are handled, which matters for a write-to-database operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the conversion/import pipeline and followed by the credential constraint. Nothing is padded, though the auth note could have been folded into a fuller usage sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool that converts and writes data into a database with no annotations and no output schema, the description covers the what and the auth mechanism but leaves the agent guessing about index parameters, target table naming, and idempotency. Adequate as a starting point, but not sufficient for confident invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 25%, so the description must compensate, and it does not: attribute_indexes and partial_attribute_indexes are undocumented in both places, and the nested connection fields (host, user, database, schema) carry no descriptions. The only parameter-adjacent information is the negative statement that no password argument exists, which is useful but narrow.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs and resources: convert the dataset to CityJSONSeq with cjio, then import it into PostgreSQL/PostGIS using cjdb. That distinguishes it from generic siblings like cityjson_import or cityjson_save because it names the exact target and toolchain, though it never explicitly contrasts itself with cityjson_import or cityjson_db_export.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance and no stated alternatives, so the agent has to infer that this (rather than cityjson_import or cityjson_export) is the path to a PostGIS database. The PGPASSWORD note is an operational prerequisite, not selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_downloadDownload CityJSON contentA
Prepare an opened or transformed dataset for download. The web host streams the managed file directly; standalone MCP clients receive an embedded application/json resource within the configured inline-size limit.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | No | Optional suggested download filename. | |
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden and does add meaningful behavior: the transport differs by client type (web host streams a managed file; standalone MCP clients get an embedded application/json resource) and output is bounded by a configured inline-size limit. It does not disclose what happens when the inline-size limit is exceeded, whether the dataset is mutated or consumed, or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste: purpose is front-loaded and the mode-dependent delivery behavior follows immediately. No repetition of schema content and no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations and no output schema, the description does well to explain the two delivery modes and the size bound. It is still incomplete on error behavior at the inline-size limit and on whether the download alters or finalizes the dataset, both of which matter for a no-annotation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (dataset_id and filename) are already fully documented in the schema. The description adds no per-parameter meaning beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a clear verb+resource ('prepare ... dataset for download') and ties it to the open/transform siblings that produce the dataset. It never distinguishes itself from the other output-path siblings (cityjson_export, cityjson_save, cityjson_db_export), so an agent cannot tell download vs export vs save from this text alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'An opened or transformed dataset' implies the prerequisite workflow (open/import/transform first), which is useful context. But there is no explicit when-to-use versus the many export/save siblings, and no exclusions or failure guidance, so selection remains partly inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_exportExport CityJSONC
Export an opened CityJSON dataset with cjio to jsonl, obj, stl, glb or b3dm.
| Name | Required | Description | Default |
|---|---|---|---|
| format | Yes | ||
| sloppy | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. | |
| destination | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it discloses very little. It does not say that a file is written to disk at the destination path, whether existing files are overwritten, what 'sloppy' changes, or whether the in-memory dataset is modified or consumed. For a tool that produces files in five different formats these are meaningful gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact sentence with no padding; the resource and the format set are front-loaded. It is terse to the point of under-specification, but that is a completeness problem rather than a verbosity one.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Four parameters, three of them required, no annotations, and no output schema to describe what comes back. An agent must guess the meaning of 'destination' and 'sloppy' and cannot know how this differs from the save/download/db_export siblings. The definition is not sufficient for reliable invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 25%: only dataset_id has a schema description. The description lists the format values (already fully captured by the enum) but explains nothing about destination (a path? a directory? a remote target?) or sloppy (tolerance for invalid geometry?). With low coverage the description should compensate and does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Export) and resource (an opened CityJSON dataset) and enumerates the supported output formats, which maps directly to the format enum. It does not differentiate itself from close siblings such as cityjson_save, cityjson_download, or cityjson_db_export, so an agent cannot tell from this text alone which export path to pick.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'an opened CityJSON dataset' implies a prerequisite (cityjson_open / cityjson_import must have run first), which is useful. But there is no explicit when-to-use vs. cityjson_save, cityjson_download, or cityjson_db_export, and no statement of when this tool is the wrong choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_extension_schemaRead a CityJSON Extension schemaB
Fetch a registered CityJSON Extension schema from the canonical cityjson.github.io registry URL.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| version | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the burden. The phrase 'Fetch ... from the canonical ... URL' conveys a read-only remote retrieval and identifies the source. It doesnot, however, disclose behavior on invalid versions, missing extensions, or the exact returned representation, which would make the behavior more transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence with no filler. The action and target are front-loaded, and the canonical URL is supplied as useful context without excess detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a low-complexity retrieval tool, and the required parameters and their formats are fully specified by the input schema. However, with no annotations and no output schema, the description is missing explicit return-value or error behavior guidance, so an agent must infer what the tool returns and how failures are signaled.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explain the semantics of 'name' or 'version'. The parameter names are self-explanatory and the JSON Schema patterns define valid formats, but the tool description itself adds no meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a specific verb+resource: fetching a registered CityJSON Extension schema from the canonical registry URL. The title and description align, and the resource is concrete enough to distinguish this from most sibling tools. However, it does not explicitly contrast itself with cityjson_extensions_registry, which is the closest sibling for registry operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The canonical registry URL and 'registered Extension schema' imply that this tool should be used when an agent needs a specific schema by name and version. There is no explicit statement about when to prefer cityjson_extensions_registry or other schema-related tools, nor any exclusionary guidance, so the usage context is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_extensions_registryBrowse CityJSON Extensions registryC
Fetch the official CityJSON Extensions registry and optionally return context around a search term.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | ||
| max_chars | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral disclosure burden. It states 'Fetch' (suggesting a read operation) but does not describe output format, truncation behavior, registry size, rate limits, or any side effects. The max_chars parameter hints at length control, but the description does not explain how the tool behaves around it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler, and it front-loads the core purpose. It is efficient for a simple fetch tool, though the optional clause could be slightly more precise about what 'context' means.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and no annotations, the description should explain what the response contains and how the parameters affect it. It does not mention the output type, what the returned context looks like, or how max_chars caps the result, leaving important details for the agent to discover.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description needs to compensate for documenting parameters. It only partially covers 'query' by referring to 'a search term,' but max_chars is completely unexplained. The description adds minimal meaning beyond the schema's raw property names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description has a specific verb ('Fetch') and a clear resource ('official CityJSON Extensions registry'), and the optional search-term context clarifies a distinct feature. However, it does not explicitly contrast with sibling tools like cityjson_extension_schema, so differentiation relies on inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for browsing the registry and optionally searching within it, but it gives no explicit guidance about when to use this tool versus alternatives. There is no mention of when not to use it or how it relates to sibling registry/extension tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_filter_lodFilter CityJSON LoDC
Keep only one level of detail using cjio lod_filter. Returns a new filename.
| Name | Required | Description | Default |
|---|---|---|---|
| lod | Yes | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses only that a new filename is returned, implying a non-destructive transformation, but says nothing about whether the original dataset remains available, whether the operation can fail on mixed-LoD input, or whether there are performance or size constraints. For a transformation tool with zero annotation coverage, this is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core action and followed by the return behavior. There is no wasted wording, though the brevity contributes to the gaps in other dimensions rather than being a structural flaw.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a dataset transformation with two required parameters, no output schema, and no annotations. The description omits the lod value format, whether the original dataset is preserved, and how the returned filename relates to other sibling tools. It is not complete enough for an agent to call this tool confidently without inspecting the schema and inferring behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: dataset_id is documented in the schema, but lod has no schema description. The tool description does not explain the accepted LoD format (for example '2.2' or '1.2') or whether multiple LoDs can be retained. With half the parameters undocumented and the description adding no parameter meaning, the description fails to compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: keep only one level of detail from a CityJSON dataset, implemented via cjio lod_filter. It also states the result is a new filename, which distinguishes it from in-place transforms. It stops short of differentiating itself from sibling transformations such as cityjson_subset or cityjson_clean_vertices.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives like cityjson_subset (which may also filter by attributes) or the other transformation tools. Prerequisites are unstated, and the agent is not told what happens to the original dataset or whether the output must be fed into a subsequent tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_get_objectGet CityObjectB
Return one complete CityObject and a computed real-world bounding box derived from referenced vertices.
| Name | Required | Description | Default |
|---|---|---|---|
| object_id | Yes | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose one genuinely useful behavior: the bounding box is computed in real-world coordinates from referenced vertices rather than stored. It says nothing about error behavior for an unknown object_id, whether the object must belong to an already-opened dataset, or whether geometry/children/parents are included in 'complete'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the primary return value leads and the secondary computed value follows. Nothing in it is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read tool with no annotations and no output schema, the description covers what is returned but leaves the object_id contract and failure modes unexplained. Adequate as a minimum, but an agent could still call it with a malformed id and be surprised.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: dataset_id is described in the schema (including where handles come from), but object_id has only a minLength constraint and no description. The description does not compensate at all — it never clarifies that the identifier is a CityJSON object id or what form it takes.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Return one complete CityObject') with an explicit scope of exactly one object, which implicitly contrasts with the listing/query siblings. It also names a second output (a computed real-world bounding box), giving a precise picture of what comes back. It stops short of naming a sibling such as cityjson_list_objects or cityjson_query as the alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance and no alternative tool is named. An agent must infer from the name alone that this is the single-object fetch versus list/query, and nothing states prerequisites such as whether the dataset must first be opened.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_importImport CityJSON from the input inboxA
Register a CityJSON file already placed in the configured input inbox and return its filename. This is for clients with an upload bridge, such as Datum. If filename is omitted, the inbox must contain exactly one JSON file.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | No | Filename shown by cityjson_list_imports or supplied by the chat application attachment metadata. | |
| display_filename | No | Original user-visible filename when an upload bridge stores the file under a generated name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full behavioral burden. It discloses the key precondition (file must already exist in the inbox) and the return value (the filename), but says nothing about what happens on filename collision, whether the file is moved or copied, permissions/configuration requirements, or error behavior when no file or multiple files are present. These are meaningful gaps for a registration mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action and return value, followed by the client-type qualifier and the fallback condition. No filler, no redundancy with the title, and each sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, no-output-schema tool, the description covers purpose, the intended client type, and the single precondition for the optional-parameter path. The remaining gap is failure-mode behavior (collisions, multiple/no files), which an agent would likely need to handle gracefully.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented, which sets the baseline at 3. The description adds one piece of real semantics beyond the schema: omitting filename requires the inbox to contain exactly one JSON file. It does not mention display_filename, leaving that entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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: "Register a CityJSON file already placed in the configured input inbox and return its filename." That clearly separates it from the upload family (cityjson_upload, cityjson_upload_start, cityjson_upload_chunk) by placing the file in an inbox rather than transferring bytes. It stops short of naming those siblings explicitly, so the differentiation is implied rather than spelled out.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear selection condition: "This is for clients with an upload bridge, such as Datum," which tells an agent when this path applies instead of a direct upload tool. It also states the precondition for omitting filename (exactly one JSON file in the inbox). What is missing is an explicit pointer to the alternative tool for clients without an upload bridge.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_import_textImport a small CityJSON text documentA
Import a small complete CityJSON document already available as text, including a small chat attachment exposed to the model by the client. Preserve the original filename. For missing, incomplete, or large attachments, use cityjson_upload.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Complete UTF-8 CityJSON document as JSON text. | |
| filename | No | Display filename used for the managed workspace copy. | import.city.json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description must carry behavior. It does disclose two useful traits: the original filename is preserved and validation of completeness is the caller's responsibility ('complete' document required). It says nothing about what the import produces, whether it mutates workspace state, or how errors on malformed JSON surface.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action and scope, followed by the preservation behavior and the fallback route. No filler and nothing repeated from the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter import tool with a fully documented schema and no output schema, the description covers what to supply, the size boundary, and where to go otherwise. The remaining gap is what happens after import (does it open, list, return an id), which a sibling like cityjson_list_imports or cityjson_open implies but the description never states.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters are described in the schema, including the 200-char cap and default filename, so the baseline is 3. The description adds only the 'complete CityJSON document' requirement for content and the filename-preservation intent, not format details or size limits beyond 'small'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (import a small complete CityJSON document already available as text) plus the scope constraint 'small', and explicitly differentiates from the sibling cityjson_upload for missing/incomplete/large cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative (cityjson_upload) and the exact conditions that select it: missing, incomplete, or large attachments. It also indicates the positive case — a complete document plus a small chat attachment — so routing is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_infoInspect CityJSONB
Return metadata, object counts, types, LoDs, attribute names, transform and extensions for an opened dataset.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden. It implies a read via 'Return', but never states that the call is non-destructive, has no side effects on the dataset, or whether it is expensive on large files. Beyond listing the fields returned, it discloses nothing about the operation's behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with the action front-loaded and every element of the returned payload enumerated; nothing is redundant or padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must, and does, enumerate what comes back (metadata, counts, types, LoDs, attributes, transform, extensions). For a one-parameter read tool this is nearly complete; only the read-only/non-destructive guarantee and the open-first prerequisite are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With one parameter and 100% schema description coverage, the schema already explains that dataset_id is a filename from cityjson_open/import or a transformation handle. The description adds only the 'opened dataset' framing, which is a marginal restatement rather than new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
A specific verb (Return) plus the exact resource (metadata for an opened dataset) and an enumerated payload: object counts, types, LoDs, attribute names, transform and extensions. An agent can distinguish it from cityjson_list_objects or cityjson_get_object, though the description never names those siblings to sharpen the distinction.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the phrase 'for an opened dataset', which hints at the prerequisite that cityjson_open/import must run first, but this is never stated as a condition. No guidance is given on when to prefer this inspection call over cityjson_list_objects, cityjson_query, or cityjson_backend_status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_list_importsList CityJSON input filesA
List JSON files in the configured input inbox. Use this when the user did not name an attached/imported file or when cityjson_import reports multiple candidates. Returns filenames only; never ask the user for an absolute path.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden, and it does disclose what the tool returns: 'Returns filenames only.' It alsotells the agent to never ask for an absolute path, which is useful interaction behavior. It could go slightly further by noting side-effect-free behavior, but the word 'list' plus the return statement make the safety profile reasonably clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, with the core purpose first, then usage conditions, then a user-interaction constraint. Every sentence adds value; there is no boilerplate or redundant text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an zero-parameter list tool with no output schema, this description is complete: it specifies the source (configured input inbox), the scope (JSON files), the return content (filenames only), the trigger conditions, and an explicit interaction constraint. Nothing critical is missing for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the input schema is an empty object, so the schema fully covers the parameter surface. The description appropriately adds no unnecessary paramter detail; the baseline of 4 for a zero-parameter tool applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
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 JSON files in the configured input inbox.' This clearly distinguishes the tool from siblings like cityjson_open or cityjson_import by indicating it is a listing operation over the input inbox, not an open/import action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use the tool: 'when the user did not name an attached/imported file or when cityjson_import reports multiple candidates.' It also instructs against asking for absolute paths, giving the agent clear behavioral guardrails. This is strong usage guidance for a simple listing tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_list_objectsList CityObjectsB
List CityObjects with IDs, types, selected attributes and LoDs. Supports filtering by CityObject type and pagination.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| types | No | ||
| offset | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. Calling it 'List' implies a read-only enumeration and 'pagination' signals result paging, but it omits the default page size of 100, the 5000 cap, and what 'selected attributes' actually means (which attributes, decided by whom). Read-only behavior and pagination are implied rather than stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler, and the resource plus returned fields are front-loaded before the optional capabilities. No restructuring needed; only the vague phrase 'selected attributes' wastes a little space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description is the only source of return-value information, and it lists the returned field categories but not their shape or nesting. For a payload-listing tool with three undocumented parameters and no annotations, it covers the essentials but leaves meaningful gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 25% — only dataset_id is documented in the schema. The description partially compensates by tying filtering to CityObject type (types) and mentioning pagination (limit/offset), but gives no format, defaults, or range guidance for any of the three undocumented parameters. That earns above-baseline but not full credit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb (List) and resource (CityObjects) and enumerates what each entry carries (IDs, types, attributes, LoDs). It is not explicitly differentiated from siblings like cityjson_query or cityjson_get_object, but the enumeration of returned fields makes the tool's role recognizable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description notes type filtering and pagination exist, but never says when to reach for this tool instead of cityjson_query, cityjson_filter_lod, or cityjson_get_object for a single object. An agent must infer the use case from the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_mergeMerge CityJSON datasetsB
Merge two or more opened CityJSON files with cjio. Returns a new filename.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_ids | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full disclosure burden. It does reveal two useful traits — inputs must already be opened and the result is a new filename (inputs presumably untouched) — but says nothing about ordering effects, CRS/metadata conflicts between datasets, or what happens on incompatible inputs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the action front-loaded and the return value appended last. It is efficient but borders on under-specified rather than optimally structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, telling the agent the return value is a filename is valuable and largely sufficient structurally. The gaps are behavioral — conflict handling and input-mutation semantics — which matter for a merge operation but are not addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is reported as 0% at the property level, and the description never mentions the single parameter 'dataset_ids' or its semantics such as ordering or minimum count. The only help comes from the nested items description in the schema itself, not from the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Merge two or more opened CityJSON files') plus the engine (cjio), which is unambiguous and no other sibling performs merging. It doesn't name a contrasting sibling, but none exists, so an agent can still place it correctly in the toolset.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'opened CityJSON files' implies the prerequisite that inputs must come from cityjson_open/import first, which is real usage guidance. However, there is no statement of when to merge versus e.g. cityjson_subset or cityjson_db_import, and no exclusions or failure conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_openOpen a CityJSON fileA
Open a CityJSON file from an optional configured project or data folder by filename, relative path, or full server-visible path. The server snapshots the file and returns its filename for later tools.
| Name | Required | Description | Default |
|---|---|---|---|
| source | Yes | CityJSON filename or relative path in an optional configured data folder, or full server-visible path. For an attached file, use cityjson_upload. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does disclose two non-obvious traits: the server snapshots the file, and the return value is a filename used by later tools. It stops short of stating whether the snapshot persists, whether it is read-only, or any error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action and source options, then the snapshot/return behavior. Every clause adds information and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no annotations and no output schema, the description covers what the tool does, where it looks, and what it returns. Missing only error/failure behavior and explicit confirmation that the snapshot does not mutate the original.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single 'source' parameter already documents all three resolution modes, so the description largely restates it. Baseline 3 is appropriate for a fully documented one-parameter schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (open a CityJSON file) and enumerates the three accepted source forms (filename, relative path, full server-visible path). It separates itself from the upload family implicitly but never names a sibling, which keeps it short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'optional configured project or data folder' phrasing hints at context, and the schema description routes attached files to cityjson_upload. However, the description itself gives no explicit when-to-use/when-not guidance against the many upload and import siblings (cityjson_import, cityjson_upload_start, etc.).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_queryQuery CityObjectsC
Query CityObjects natively by IDs, types, 2D bbox and attribute predicates. Attribute predicates support eq, neq, gt, gte, lt, lte, contains and in.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | ||
| bbox | No | 2D bbox [minX, minY, maxX, maxY] in the dataset CRS. | |
| limit | No | ||
| types | No | ||
| offset | No | ||
| attributes | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full behavioral burden and discloses very little. It never states that this is a read-only operation, how results are ordered or paginated, that results are capped (limit default 100, max 5000), or whether filters combine with AND semantics. 'Natively' is the only hint about execution mode and is left unexplained.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the capability and followed by the operator list an agent needs to build a predicate. No filler, though the second sentence could have been spent on behavioral detail rather than an operator enumeration alone.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a seven-parameter, nested-object query tool with no annotations and no output schema, the description is thin. It omits prerequisites (dataset must be opened first), result shape, pagination/limit behavior, and predicate combination semantics, leaving real gaps an agent would hit on first invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 29% across seven parameters, so the description must compensate; it does so partially by naming ids, types, bbox and attributes, and by enumerating the supported attribute operators (eq, neq, gt, gte, lt, lte, contains, in), which the schema does not spell out. However, limit, offset, and how the attributes object maps keys to operators are undocumented in both places.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Query CityObjects') and enumerates the four filter dimensions (IDs, types, 2D bbox, attribute predicates), which clearly delimits what the tool can select. It does not name or contrast with close siblings such as cityjson_list_objects, cityjson_get_object, or cityjson_subset, so the agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance, no statement of when-not-to-use, and no named alternatives. An agent cannot tell from the description whether this supersedes cityjson_list_objects or cityjson_subset, nor whether it requires that a dataset already be open.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_remove_materialsRemove CityJSON materialsB
Remove all materials with cjio. Returns a new filename.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full behavioral burden. It discloses that the operation returns a new filename, which usefully implies a non-destructive output pattern, but it does not state whether the original dataset is modified, whether the operation is reversible, or what permissions are required for this mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no wasted words, and the primary action is front-loaded ahead of the return behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-parameter mutation tool without an output schema, the description is minimally adequate: it names the operation and the return type. However, it omits behavioral details that matter for a destructive transformation, such as whether the original data is preserved and how the result should be used downstream.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single dataset_id parameter, so the schema already explains its source and compatibility. The description adds no parameter-specific detail beyond what the schema provides, making the baseline of 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — 'Remove all materials with cjio' — which is clear and distinguishable from most siblings. However, it does not explicitly differentiate itself from the closely related cityjson_remove_textures sibling, leaving some ambiguity about which removal tool to choose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives such as cityjson_remove_textures or cityjson_attribute_remove. The description gives no context about prerequisites, when-not-to-use conditions, or workflow placement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_remove_texturesRemove CityJSON texturesB
Remove all textures with cjio. Returns a new filename.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It does disclose one genuinely useful behavioral fact — the operation returns a new filename rather than mutating in place — but says nothing about whether the source dataset survives, whether removal is reversible, or what happens on a textured-less input.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, the action front-loaded and the return value second; nothing is wasted. The brevity is efficient but leaves the gaps noted in other dimensions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no output schema, the definition covers the action and the shape of the return (a filename). It omits the fate of the input dataset and any preconditions, which an agent would want before chaining into a subsequent call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (dataset_id) with 100% schema description coverage that already explains accepted filename provenance and internal handles. The description adds no further meaning about the identifier, which is acceptable at this coverage level.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Remove all textures") plus the engine used (cjio), which clearly separates it from siblings like cityjson_remove_materials or cityjson_attribute_remove. It does not explicitly name those near-neighbours, so the differentiation is inferable rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of the closest alternatives (remove_materials, attribute_remove). An agent must infer from the name alone that this is a strip-textures step rather than a general cleanup.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_reprojectReproject CityJSONA
Reproject coordinates to a target EPSG CRS with cjio. The source file must already define a CRS. Returns a new filename.
| Name | Required | Description | Default |
|---|---|---|---|
| epsg | Yes | ||
| digit | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden. It usefully discloses the underlying engine (cjio) and that the result is a new artifact ('Returns a new filename'), implying the input dataset is not mutated in place. It stops short of stating failure behavior when no CRS is present, whether intermediate datasets accumulate, or how the new file relates to the original dataset_id.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action before the precondition and the return value. Every clause carries information and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a coordinate-transforming mutation tool with no annotations and no output schema, the definition covers the core action, the precondition, and the return shape. It leaves gaps on how the undocumented 'digit' parameter behaves, what happens to the source dataset, and how errors surface when the CRS is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 33%, so the description must compensate. It effectively explains 'epsg' as the target CRS and hints that 'dataset_id' is a filename handle ('Returns a new filename'), which aligns with the schema note. The 'digit' parameter receives no explanation at all in either the schema or the description, leaving one of three parameters opaque, which caps this below a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource ('Reproject coordinates to a target EPSG CRS') and names the engine ('with cjio'), so the operation is unambiguous. It does not explicitly contrast itself with near-siblings like cityjson_assign_crs or cityjson_translate, which is the only thing keeping it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
One real prerequisite is stated: 'The source file must already define a CRS,' which tells the agent a precondition for calling. However there is no guidance on when to choose this over cityjson_assign_crs (which sets a CRS) or cityjson_translate (which shifts coordinates), and no mention of what to do if the precondition fails.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_saveSave CityJSONC
Copy an opened/derived CityJSON dataset to an explicit destination path.
| Name | Required | Description | Default |
|---|---|---|---|
| overwrite | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. | |
| destination | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden. 'Copy' usefully implies the source dataset is left intact, but it says nothing about what happens when the destination already exists, how the overwrite flag (default false) behaves, required permissions, or whether the destination must be inside a server-managed directory.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the verb and target come first. It is efficient, though it is arguably too terse for a write operation with an undocumented overwrite flag.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a filesystem-writing tool with three parameters, no annotations, no output schema, and low schema description coverage, so the description should explain overwrite behavior and return value. Instead it gives one sentence, leaving the agent guessing about the overwrite default's effect and failure modes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%: dataset_id is documented in the schema, while destination and overwrite are bare. The description re-states that the destination is an explicit path but adds no path format, relative-vs-absolute rules, or overwrite semantics, so the undocumented parameters remain unexplained in both places.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Copy') and resource ('opened/derived CityJSON dataset') and states the output target ('explicit destination path'), so the agent can picture the operation. It does not differentiate itself from close siblings such as cityjson_export, cityjson_db_export, or cityjson_download, which also move dataset content out.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus cityjson_export, cityjson_download, or cityjson_db_export, nor any stated prerequisites beyond 'opened/derived'. The agent must infer the selection rule from the word 'explicit destination path' alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_schema_readRead CityJSON JSON SchemaA
Fetch one canonical CityJSON 2.0.2 JSON Schema by name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | cityjson.schema.json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. The verb 'Fetch' clearly indicates a read-only retrieval operation, and 'canonical ... JSON Schema' identifies the domain. It does not describe the response shape, error behavior, or whether the raw JSON is returned directly, but these are low-risk details for a simple fetch.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, tightly worded sentence with no wasted content. It front-loads the action, resource, version, and selection method immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with an enum and default in the schema, the description is mostly sufficient: it tells the agent what is fetched and how selection works. It lacks explicit return-value or usage-context details, and there is no output schema, but the low complexity makes this an acceptable gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description adds only 'by name', which is minimal. However, the single 'name' parameter is fully constrained by an enum and a default in the input schema, so the parameter is still unambiguous. The description adds modest context by framing these as canonical CityJSON 2.0.2 schemas, but does not explain how to choose among the enum values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetch'), exact resource ('one canonical CityJSON 2.0.2 JSON Schema'), and selection mechanism ('by name'). The 'canonical' qualifier helps distinguish this from related schema or specification tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit usage guidance is provided, and no alternative tools are named. The phrase 'canonical CityJSON 2.0.2' implies official schemas, but the agent is left to infer when to choose this over sibling tools like cityjson_extension_schema or cityjson_spec_read.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_spec_outlineCityJSON specification outlineA
Return the bundled outline and canonical URLs for the current CityJSON specification and schemas.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral disclosure burden. 'Return' clearly signals a read-only information retrieval operation, and 'bundled' implies the data is local rather than fetched remotely. It identifies what is returned without detailing exact formatting, but for a zero-parameter informational tool that is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence with no redundant phrasing; the verb and object are front-loaded so an agent immediately knows what the tool does. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity, zero parameters, no output schema, and no annotations, the description is nearly complete for safe invocation. It names both output components, outline and canonical URLs. A brief pointer to cityjson_spec_read for full content would improve context, but is not required for correct usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the baseline is 4. The description does not need to explain parameter behavior, and the empty schema leaves nothing unknown for caller preparation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Return') and a concrete resource: the bundled outline and canonical URLs for the current CityJSON specification and schemas. This is clearly distinct from siblings like cityjson_spec_read and cityjson_schema_read, which imply reading actual content rather than an outline and URLs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a quick-reference retrieval use, but there is no explicit when/when-not guidance or mention of alternatives. An agent is not told to choose this over cityjson_spec_read or cityjson_schema_read, though the purpose makes the intended context reasonably inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_spec_readRead CityJSON specificationA
Fetch the canonical CityJSON 2.0.2 living specification and return either the beginning or a context window around a search query.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | ||
| max_chars | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description conveys a read-only operation and the conditional behavior based on whether a query is supplied. With no annotations and no output schema, though, it does not explain how max_chars affects the returned text, what format the text takes, or how the context window is determined.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler. It efficiently covers the source, version, and two output modes without wasting words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool this is mostly adequate, but it leaves gaps around max_chars semantics, output format, and how this relates to sibling spec tools. The absence of annotations and an output schema increases the burden on the description, and those gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The query parameter gains some meaning from 'context window around a search query' and 'beginning' when absent. However, max_chars is not mentioned at all, and with 0% schema description coverage, the agent must infer its behavior solely from the parameter name and constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Fetch'), a specific resource ('canonical CityJSON 2.0.2 living specification'), and a clear output behavior (beginning or context window around a search query). This distinguishes it from sibling tools like cityjson_spec_outline and cityjson_schema_read, which target other spec artifacts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The use case is implied: retrieve spec text, optionally near a search query. However, the description never states when to choose this over cityjson_spec_outline or cityjson_schema_read, and it provides no exclusions or alternative conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_subsetCreate CityJSON subsetB
Create a derived CityJSON subset with cjio using IDs, bbox, radius, random count or CityObject types. Returns a new filename.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | No | ||
| bbox | No | 2D bbox [minX, minY, maxX, maxY] in the dataset CRS. | |
| types | No | ||
| radius | No | ||
| random | No | ||
| exclude | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full disclosure burden. It does usefully state that the output is a derived dataset plus a new filename, implying the source dataset is not destroyed, but it is silent on whether selectors combine or are mutually exclusive, what happens when nothing matches, and what 'exclude' inverts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action and followed immediately by the return value. 'with cjio' is implementation detail, but it is short and the rest of the text earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, mutation-style operation with no annotations and no output schema, the description covers the return value ('a new filename') but leaves selector interaction rules and the non-destructive guarantee implicit. It is adequate to attempt a call but not complete enough to guarantee a correct one.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 29% across 7 parameters, so the description must compensate. It does name five of the seven selector parameters (ids, bbox, radius, random, types), which adds meaning over their bare types, but it never explains 'exclude', the mutual exclusivity of selectors, or the required dataset_id contract.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Create a derived CityJSON subset') and enumerates the five selection modes (IDs, bbox, radius, random count, CityObject types). It is clear what the tool produces, though it does not name any sibling it supersedes or contrasts with, so an agent must infer the boundary against cityjson_filter_lod or cityjson_query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The enumeration of selection criteria implies the situations the tool is for, but there is no explicit when-to-use / when-not-to-use framing and no named alternative. An agent can guess that this is the extraction tool, but cannot tell from the text whether it should prefer this over cityjson_query or cityjson_filter_lod.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_to_citygmlConvert CityJSON to CityGMLB
Convert an opened CityJSON dataset to CityGML using citygml-tools. The installed citygml-tools version controls the default target encoding.
| Name | Required | Description | Default |
|---|---|---|---|
| crs_name | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. | |
| output_directory | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden. It does disclose genuinely non-obvious behavior — that citygml-tools performs the conversion and that the installed version determines the default target encoding — but it says nothing about what artifact is produced, where it lands (output_directory), whether the source dataset is consumed or preserved, or what happens on failure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action and resource, with no filler. It is efficient, though its brevity is part of why other dimensions are under-specified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations, no output schema, and two of three parameters undocumented, the definition is thin for a conversion tool. An agent cannot tell what the call returns (a file path, a dataset handle, or an inline GML payload) or what crs_name/output_directory do, which is required information to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 33%: dataset_id is documented, but crs_name and output_directory are undocumented in both schema and description. The description never mentions reprojection/crs handling or output location, so it fails to compensate for the coverage gap; only the encoding remark loosely touches target-format behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource pair ('Convert an opened CityJSON dataset to CityGML') plus the underlying engine (citygml-tools). The direction of conversion distinguishes it implicitly from the reverse-direction sibling citygml_to_cityjson, though it never names that sibling or cityjson_export explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the word 'opened' hints that a dataset must first be opened via cityjson_open/cityjson_import, and the conversion direction makes the general use case obvious. There is no explicit guidance on when to choose this over cityjson_export or how it differs from the reverse converter, and no stated preconditions or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_translateTranslate CityJSON coordinatesB
Translate CityJSON coordinates with cjio. With minxyz, coordinates are shifted relative to the supplied minimum; without it cjio uses the model minimum.
| Name | Required | Description | Default |
|---|---|---|---|
| minxyz | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full behavioral burden. It discloses the two coordinate-shift modes, but says nothing about whether the dataset is mutated in place or a new dataset handle is returned, what the response looks like, whether repeated application compounds the shift, or what units/axis order are assumed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the action front-loaded and no filler; the conditional minxyz behavior is packed into the single follow-on clause. Slightly compressed phrasing ('with minxyz ... without it') costs a little clarity but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless-annotation, no-output-schema mutation tool, the description leaves out the most decision-relevant facts: in-place vs returned dataset, effect on the dataset_id handle, and coordinate conventions. Given the complexity of geometry transformation, this is under-specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: dataset_id is documented in the schema, while minxyz is not, and the description does compensate by explaining that minxyz defines the shift origin versus defaulting to the model minimum. It still does not specify the coordinate ordering, units, or CRS implications of the three-element array.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Translate CityJSON coordinates') and names the underlying engine (cjio), so an agent can tell it apart from siblings like cityjson_reproject or cityjson_clean_vertices. It stops short of explicitly contrasting itself with those siblings, so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it (coordinate shifting/minimum-normalization) and explains the two operating modes via minxyz. It gives no explicit when-not guidance and never mentions the nearby alternatives cityjson_reproject or cityjson_assign_crs, which an agent could easily confuse with a coordinate transform.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_triangulateTriangulate CityJSONB
Triangulate surfaces with cjio. Use sloppy=true only when the robust triangulator fails.
| Name | Required | Description | Default |
|---|---|---|---|
| sloppy | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It does not say whether triangulation mutates the dataset in place or produces a new dataset handle, whether it is reversible, whether textures/materials survive it, or how expensive it is — critical omissions for a geometry-mutating operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, action first and parameter caveat second, with no redundant restatement of the name or title. Nothing could be removed without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations and no output schema, the definition should cover mutation semantics and result handling, and it does neither. For a geometry-rewriting tool the agent is left guessing whether the dataset_id stays valid after the call and what the response looks like.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%: dataset_id is documented in the schema, while sloppy has no schema description. The description compensates by explaining what sloppy means functionally (a less robust fallback path) and when to enable it, which is meaningful context beyond the boolean default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Triangulate surfaces') and identifies the underlying engine ('with cjio'), so an agent knows exactly what operation is performed. It does not, however, distinguish this tool from neighbors that also alter geometry (e.g. cityjson_clean_vertices, cityjson_filter_lod), so sibling differentiation is absent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is one explicit conditional: 'Use sloppy=true only when the robust triangulator fails', which correctly frames sloppy as a fallback. However, there is no guidance on when triangulation itself is needed versus other geometry operations, and no prerequisites (e.g. valid geometry, suitable LoD) are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_upgradeUpgrade CityJSONB
Upgrade an older supported CityJSON file to the version supported by the installed cjio.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden, yet it never says whether the upgrade mutates the referenced dataset in place, produces a new dataset_id, or leaves the original intact. It also omits whether the call fails on already-current files and what error or return the agent should expect after a mutation-style operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the key constraint (older supported version) appears before the target version. It is arguably terse to a fault, but nothing is wasted or buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations, no output schema, and a write-like operation, the definition leaves the agent guessing about the outcome: in-place mutation versus new dataset handle, preservation of the source file, and failure behavior. For an upgrade/migration tool that is a meaningful completeness gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single dataset_id parameter is fully documented in the schema, including its origin from cityjson_open/import and handle compatibility. The description adds no further semantics about that parameter, so the baseline of 3 applies when the schema does the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Upgrade ... CityJSON file') and bounds the scope to 'older supported' inputs targeting the version of the installed cjio. That is enough to distinguish it from validation, export, save, or format-conversion siblings, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Use is implied by the phrase 'older supported CityJSON file', which tells the agent this is for outdated data rather than fresh imports. However, there is no explicit when-not guidance, no mention of what to do for unsupported versions, and no stated alternative such as re-importing the source.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_uploadUpload a CityJSON fileA
Open an in-chat file picker to upload a CityJSON file directly. Use this when the user attached or wants to choose a file that is not visible to the MCP server. The file is transferred outside the model context; no project folder or workspace setup is needed. Pass the user’s question so the app can continue after upload.
| Name | Required | Description | Default |
|---|---|---|---|
| question | No | The user’s question about the file, to continue after the upload finishes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full disclosure burden and does more than most: it states the interaction happens in-chat via a picker, that the bytes are streamed 'outside the model context,' and that no project folder or workspace setup is required. What it omits is the outcome side — whether the call blocks on user selection, what happens if the user cancels, and whether the file becomes server-visible afterwards.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with the action, then the when-to-use condition, then the transfer mechanics. Nothing is padding, though the workspace/setup sentence is the weakest and could be folded into the transfer note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and no annotations, so the description is the only source of truth, and it stops short of saying what the call returns or what state the file lands in (upload handle, server-side object, or nothing). For an interactive UI-triggering tool that is a meaningful hole, even though the interaction model and precondition are well covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single parameter, so the baseline is already high. The description still adds purpose the schema lacks justification for: the question is 'passed' so 'the app can continue after upload,' explaining why a question string accompanies a file transfer. It could have added whether the question is required in practice despite being optional.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Open an in-chat file picker to upload a CityJSON file directly.' An agent immediately knows this is an interactive upload entry point rather than a server-side ingest. However, it never distinguishes itself from the closely named siblings cityjson_upload_start/_chunk/_finish or from cityjson_import, so the boundary has to be inferred.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit triggering condition: 'Use this when the user attached or wants to choose a file that is not visible to the MCP server.' That is a real discriminator against server-visible import paths. The gap is that the chunked-upload siblings are never mentioned as alternatives or as a follow-on chain, leaving the agent to guess whether this single call replaces that flow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_upload_cancelCancel CityJSON uploadC
Discard an unfinished CityJSON upload.
| Name | Required | Description | Default |
|---|---|---|---|
| upload_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. "Discard" hints at a destructive operation, but it never states whether the upload and its uploaded chunks are permanently removed, whether the action is reversible or resumable, whether special permissions are needed, or what error occurs for an invalid or already-finished upload.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with zero filler, and the key concept (discard an unfinished upload) is front-loaded. It is efficient but borders on under-specified rather than being tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive, annotation-free cancel operation with an undocumented required parameter and no output schema, the description leaves out essential context: irreversibility, the origin of upload_id, and expected outcomes. An agent could invoke it but cannot predict its side effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the only parameter, upload_id, has no documentation anywhere beyond its name and UUID format. The description does not explain where an agent obtains the upload ID (presumably from cityjson_upload_start) or that it must reference a still-open upload.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ("Discard an unfinished CityJSON upload"), which cleanly separates it from siblings like cityjson_upload_finish and cityjson_upload_chunk. It stops short of naming those alternatives explicitly, but the intent is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the qualifier "unfinished" signals the tool applies to an in-progress upload, so an agent can infer it is not for completed uploads. There is no explicit statement of when to choose cancel versus finish, or what happens if the upload is already complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_upload_chunkSend CityJSON upload chunkC
Send the next chunk from the CityJSON file picker.
| Name | Required | Description | Default |
|---|---|---|---|
| bytes | Yes | ||
| offset | Yes | ||
| upload_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of explaining behavior, but it only weakly implies a stateful upload operation. It does not disclose sequencing requirements, retry or idempotency behavior, offset validation, chunk limits in practical terms, error handling, or what server-side state is changed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single short sentence is direct and front-loads the operation without filler. Its brevity comes at the cost of essential protocol details, and the file-picker wording is less precise than describing a chunk of file data.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a stateful chunked-upload tool with three undocumented required parameters, no annotations, and no output schema, the description is insufficient for reliable invocation. It needs the surrounding start/chunk/finish workflow, byte encoding and offset rules, and expected sequencing or response behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explain any of the three required parameters. In particular, it omits where upload_id comes from, whether bytes is base64 or another encoding, and whether offset is a byte offset that must match the accumulated upload length.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a clear action and resource: sending the next chunk of a CityJSON upload. It distinguishes the operation from starting or finishing an upload, but 'from the CityJSON file picker' is vague and does not explain the upload-session workflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The word 'next' implies that this is used after an upload has begun and that chunks are sent sequentially. However, it never explicitly directs the agent to call cityjson_upload_start first, repeat this tool until all bytes are sent, or use cityjson_upload_finish or cityjson_upload_cancel afterward.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_upload_finishFinish CityJSON uploadC
Validate and register the uploaded CityJSON file.
| Name | Required | Description | Default |
|---|---|---|---|
| upload_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It states that validation and registration occur, implying mutation, but omits validation failure behavior, whether upload_id is consumed, idempotency, required permissions, and what registration changes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no redundant wording. It is efficiently sized for the information it conveys, though that information is limited.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a side-effecting finalization tool with no annotations, no output schema, and an undocumented upload_id, the definition is too sparse. It omits workflow prerequisites, validation failure outcomes, and return/registration details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single required upload_id parameter has 0% schema description coverage, and the description does not mention it or explain that it comes from the upload workflow. The UUID format is in the schema, but the semantic linkage to upload_start/chunk is missing; only the parameter name supplies meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb combination ('Validate and register') and resource ('uploaded CityJSON file'), making the tool's function clear. It does not distinguish this finalization step from sibling tools such as cityjson_validate or cityjson_upload, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides no explicit when-to-use guidance or prerequisites. It does not say that it should follow cityjson_upload_start/chunk, nor when to choose it over cityjson_validate or cityjson_upload; only the word 'finish' implies sequencing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_upload_startStart CityJSON uploadC
Start an upload from the CityJSON file picker.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| size_bytes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure and provides almost none. It does not say what the call returns (presumably an upload identifier), whether the upload expires, what happens if it is never finished, or what permissions are needed. For a state-creating operation in a multi-step protocol this is a significant gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single front-loaded sentence with no wasted words, but the brevity comes at the cost of under-specification rather than efficiency. There is no structure such as a follow-up step or return-value note to anchor the agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is the entry point of a four-part upload protocol (start/chunk/finish/cancel) with two required parameters, no annotations, and no output schema. The definition omits the sequencing contract, the returned handle, and any size or format constraints, leaving the agent unable to complete the workflow from this description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description mentions neither parameter. The agent must guess whether filename needs a path or just a basename, and whether size_bytes is used for validation or quota checks. Nothing is added beyond the bare property names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Start') and resource ('an upload'), and 'from the CityJSON file picker' hints at the UI origin. However, it never states what distinguishes this from cityjson_upload_chunk, cityjson_upload_finish, or cityjson_upload itself, so an agent must infer that this is step one of a multi-part flow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this versus the sibling upload tools, no mention that chunk/finish calls must follow, and no preconditions such as file type or size limits. The only usage hint is the word 'Start', which implies a sequence without describing it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_validateValidate CityJSON completelyB
Run cjval and val3dity and return one combined structural + geometric validation result. geometry.reportSummary contains the complete invalidObjectIds list for reliable follow-up subsets.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden. It usefully discloses that two engines run underneath and points to geometry.reportSummary for the complete invalidObjectIds list, which is real value. But it says nothing about whether the dataset is mutated, expected runtime cost of geometric validation, or failure behavior on malformed input.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero padding, and the core action plus its engine composition are front-loaded. The second sentence earns its place by warning where the untruncated ID list lives.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must convey the return shape, and it only describes one nested field path (geometry.reportSummary.invalidObjectIds). The structural half of the combined result is left undescribed, leaving the agent to discover the rest of the payload by calling it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single dataset_id parameter is already documented in the schema, including the provenance of the value ('Filename returned by cityjson_open...'). The description adds no additional meaning about the identifier, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Run cjval and val3dity') and resource ('structural + geometric validation'), and the word 'combined' implicitly positions it as the superset of cityjson_validate_schema and cityjson_validate_geometry. It stops short of naming those siblings, so an agent must infer the distinction from the adjective alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'one combined ... result' suggests this is the full check versus the narrower sibling validators, and the follow-up mention hints at subsetting invalid objects. There is no explicit when-to-use/when-to-prefer-a-sibling statement or cost warning for running both engines.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_validate_geometryValidate 3D geometryB
Validate CityJSON 3D primitives with val3dity according to ISO 19107 concepts and CityJSON-specific geometric checks. Returns a detailed report plus a compact reportSummary containing every invalid object ID and error-code count.
| Name | Required | Description | Default |
|---|---|---|---|
| verbose | No | ||
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full behavioral burden and does disclose the return shape: a detailed report plus a compact reportSummary enumerating invalid object IDs and per-error-code counts. It never states that the operation is non-mutating/read-only or what happens on an invalid dataset, which matters when annotations are absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, and the core action is front-loaded before the return-value sentence. Nothing is redundant, though the second sentence is a dense list that could be split for scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description rightly spends its second sentence on return values, which covers the biggest gap. Still missing: the meaning of 'verbose', the read-only nature of validation, and any hint about runtime or limits on large datasets, which an agent needs before invoking it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50%: dataset_id is documented in the schema as coming from cityjson_open/cityjson_import, and the description adds nothing to it. The 'verbose' parameter has no description anywhere yet plainly affects the reported output size, and the description misses the chance to explain it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (validate) and resource (CityJSON 3D primitives), and pins the engine and standard: val3dity, ISO 19107, CityJSON-specific geometric checks. That scope implicitly separates it from cityjson_validate and cityjson_validate_schema, but no sibling is ever named, so the differentiation is inferred rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the phrase '3D primitives ... geometric checks' – an agent can guess this is the geometry-check complement to schema validation, but there is no statement of when to prefer it over cityjson_validate or cityjson_validate_schema, and no prerequisite (e.g. a loaded dataset) is spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cityjson_validate_schemaValidate CityJSON syntax and schemaB
Validate a dataset with the official cjval validator: JSON syntax, CityJSON schemas, extensions and additional structural consistency checks.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_id | Yes | Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility. | |
| extension_schemas | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses that validation is delegated to the official cjval validator and what categories of problems are checked, which is meaningful context. However, it is silent on whether errors are returned as a list or a pass/fail flag, whether validation is read-only, and how long a large dataset might take.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the validator name and check list are the most useful information and appear immediately. Slight density in the comma list but nothing that should be cut.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No annotations and no output schema, so the description is the only source of behavioral information. It covers what is checked but leaves the caller unsure what a result looks like and how to trigger extension-aware validation, which matters for a two-parameter tool with one undocumented parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 50%: dataset_id is documented in the schema, but extension_schemas has no description. The description mentions "extensions" as something validated but never explains that the caller can supply custom extension schema identifiers or paths, so it does not compensate for the gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (Validate) and resource (a CityJSON dataset) and enumerates the check classes performed: JSON syntax, CityJSON schemas, extensions, and structural consistency. This implicitly distinguishes it from cityjson_validate_geometry (geometry-only checks), though that sibling is never named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the enumerated check types — an agent can infer this is the full schema-level check versus the geometry-only sibling, but there is no explicit "use this when..." or "use cityjson_validate_geometry instead for..." statement. No prerequisites (e.g., dataset must be loaded first) are stated.
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.
32 tool updates
v0.3.0- Changed
cityjson_assign_crs1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_attribute_remove1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_attribute_rename1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_clean_vertices1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_db_import1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_download1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_export1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_filter_lod1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_get_object1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_import1 field changed- added
Input schema / properties / display_filenameAdded value: +{ + "description": "Original user-visible filename when an upload bridge stores the file under a generated name.", + "maxLength": 255, + "minLength": 1, + "type": "string" +}
- Changed
cityjson_info1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_list_objects1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_merge1 field changed- changed
Input schema / properties / dataset_ids / items / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_open1 field changed- changed
Input schema / properties / source / descriptionPrevious value: -"Full server-visible path inside an allowed root. This cannot be a path from a chat attachment."New value: +"CityJSON filename or relative path in an optional configured data folder, or full server-visible path. For an attached file, use cityjson_upload."
- Changed
cityjson_query1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_remove_materials1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_remove_textures1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_reproject1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_save1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_subset1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_to_citygml1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_translate1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_triangulate1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_upgrade1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Added
cityjson_upload - Added
cityjson_upload_cancel - Added
cityjson_upload_chunk - Added
cityjson_upload_finish - Added
cityjson_upload_start - Changed
cityjson_validate1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_validate_geometry1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
- Changed
cityjson_validate_schema1 field changed- changed
Input schema / properties / dataset_id / descriptionPrevious value: -"Dataset handle returned by cityjson_import, cityjson_open, cityjson_import_text, or another transformation tool."New value: +"Filename returned by cityjson_open, cityjson_import, or a transformation. Internal dataset handles also work for compatibility."
37 tool updates
v0.1.0- First observed
citygml_to_cityjson - First observed
cityjson_assign_crs - First observed
cityjson_attribute_remove - First observed
cityjson_attribute_rename - First observed
cityjson_backend_status - First observed
cityjson_clean_vertices - First observed
cityjson_db_export - First observed
cityjson_db_import - First observed
cityjson_download - First observed
cityjson_export - First observed
cityjson_extension_schema - First observed
cityjson_extensions_registry - First observed
cityjson_filter_lod - First observed
cityjson_get_object - First observed
cityjson_import - First observed
cityjson_import_text - First observed
cityjson_info - First observed
cityjson_list_imports - First observed
cityjson_list_objects - First observed
cityjson_merge - First observed
cityjson_open - First observed
cityjson_query - First observed
cityjson_remove_materials - First observed
cityjson_remove_textures - First observed
cityjson_reproject - First observed
cityjson_save - First observed
cityjson_schema_read - First observed
cityjson_spec_outline - First observed
cityjson_spec_read - First observed
cityjson_subset - First observed
cityjson_to_citygml - First observed
cityjson_translate - First observed
cityjson_triangulate - First observed
cityjson_upgrade - First observed
cityjson_validate - First observed
cityjson_validate_geometry - First observed
cityjson_validate_schema
TDQS
Scored across 42 tools
Most tools target a distinct operation, but two clusters overlap heavily: the upload/import family (cityjson_upload, cityjson_upload_start, cityjson_upload_chunk/finish/cancel, cityjson_import, cityjson_import_text, cityjson_open, cityjson_list_imports) and the validation family (cityjson_validate, cityjson_validate_schema, cityjson_validate_geometry). Descriptions do provide guidance on when to use each, but an agent must read carefully to avoid misselection.
All tools use a consistent snake_case cityjson_-prefixed verb_noun pattern (cityjson_validate_geometry, cityjson_subset, cityjson_reproject, etc.), which is highly predictable. A few exceptions are noun-only (cityjson_info, cityjson_download, cityjson_backend_status) but these remain readable and consistent in style.
42 tools is heavy for the stated scope and pushes well past the 15-tool guideline, especially since much of the surface is protocol plumbing (upload chunk/finish/cancel) and redundant validation entry points. The set feels over-expanded rather than tightly scoped.
Coverage of the CityJSON lifecycle is strong: ingestion, validation, spatial/CRS transforms, geometry cleanup, subsetting, format conversion, DB import/export, querying, and spec/schema lookups are all present. Minor gaps exist around mutating object data—no attribute-set/add or object creation/deletion tools—but core workflows are covered.
Maintenance
Related MCP Connectors
Headless CAD engine & MCP server for 2D/3D drafting, solids, DXF/SVG export, and automation.
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
MCP Spec Compliance MCP — audits any MCP server.json against the official Model Context Protocol
MCP server for the GDEX (Geoscience Data Exchange) data portal: datasets, files, metrics, subsetting
Related MCP Servers
- AlicenseBqualityBmaintenanceProvides MCP tools for CPACS-oriented TiGL workflows, enabling lifecycle management, inspection, export, and parameter manipulation of aircraft geometry models without native geometry runtimes.113MIT
- AlicenseNot gradedqualityDmaintenanceBrowser-based geometry processing server that enables AI agents to create geometry, run analysis and operators, inspect results, and take screenshots via MCP.48 npm6MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents and software to create, edit, inspect, validate, and export CAD geometry through MCP using backend-neutral typed operations, with FreeCAD/OpenCascade as the authoritative B-rep backend and JSCAD preview.1Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to perform geospatial analysis, spatial data processing, vector and raster operations, coordinate transformations, spatial statistics, mapping, and access to climate, satellite, and other geospatial data through MCP-compatible clients.MIT