Skip to main content
Glama
Yarroudh

cityjson-mcp

by Yarroudh

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 --> KNOW

Descargar 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.

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 --> KNOW

Descargar 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 con cityjson_download.

Un cliente MCP puede resolver esa solicitud aproximadamente como:

  1. cityjson_import

  2. cityjson_validate

  3. cityjson_subset

  4. cityjson_reproject

  5. cityjson_clean_vertices

  6. cityjson_validate

  7. cityjson_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 .env

Seleccione 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.com

Este 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 chat

Luego 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 loop

npm run chat es equivalente a:

docker compose -f docker/docker-compose.chat.yml up --build

La 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:latest

Confirme que todos los backends estén presentes:

docker run --rm --entrypoint node yarroudh/cityjson-mcp:latest /app/scripts/doctor.mjs

La 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.json y 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:doctor

Si 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 install

Luego verifique el código fuente y las pruebas nativas:

npm run check
npm test

Compruebe qué backends externos están disponibles:

npm run doctor

El 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-binary

val3dity

Proyecto oficial: https://github.com/tudelft3d/val3dity

En macOS, el proyecto upstream proporciona una fórmula Homebrew:

brew tap tudelft3d/software
brew install val3dity

En 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 cjdb

cjdb 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-models

El 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/cjdb

Para 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 test

Luego 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.json

  • Windows: %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.json

Reinicie 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.json

Configuración global:

~/.cursor/mcp.json

Ejemplo:

{
  "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_validate en 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.json

Ejemplo:

{
  "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 --> TOOLS

Descargar PNG — alta resolución


Catálogo de herramientas

Conjunto de datos y diagnósticos

Tool

Backend

Propósito

Entradas clave

cityjson_backend_status

nativo

Informa si cjio, cjval, val3dity, citygml-tools y cjdb son invocables; también devuelve la configuración de la política de rutas.

ninguna

cityjson_list_imports

nativo

Lista los nombres de archivos JSON disponibles en la bandeja de entrada configurada.

ninguna

cityjson_import

nativo

Importa un archivo de la bandeja de entrada por nombre y devuelve un dataset_id inmutable.

filename opcional

cityjson_import_text

nativo

Alternativa de texto corto para clientes programáticos; el contenido viaja a través del JSON de MCP.

content, filename opcional

cityjson_open

nativo

Abre un archivo JSON CityJSON normal y devuelve un dataset_id más un resumen estructural.

source

cityjson_upload

nativo

Alias de compatibilidad obsoleto de cityjson_import_text; no es una subida binaria.

content, filename opcional

cityjson_download

nativo

Prepara un modelo abierto o transformado para su transmisión web directa o una descarga MCP integrada.

dataset_id, filename opcional

cityjson_info

nativo

Resume tipo/versión, recuentos de objetos, LoDs, atributos, metadatos, transformación y extensiones.

dataset_id

cityjson_save

nativo

Copia un conjunto de datos abierto/derivado a una ruta autorizada explícita.

dataset_id, destination, overwrite

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

cityjson_list_objects

nativo

Lista paginada de CityObjects con ID, tipo, atributos, LoDs y relaciones.

dataset_id, types, limit, offset opcionales

cityjson_get_object

nativo

Devuelve un CityObject completo y calcula su bbox 3D a partir de los vértices referenciados.

dataset_id, object_id

cityjson_query

nativo

Filtra por IDs, tipos de CityObject, bbox 2D y predicados de atributos.

dataset_id, ids, types, bbox, attributes, paginación

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:

  • eq

  • neq

  • gt

  • gte

  • lt

  • lte

  • contains

  • in

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 --> COMBINE

Descargar PNG — alta resolución

Tool

Backend

Propósito

Entradas clave

cityjson_validate_schema

cjval

Validación oficial de sintaxis/esquema y coherencia estructural de CityJSON.

dataset_id, extension_schemas locales opcionales

cityjson_validate_geometry

val3dity

Valida las primitivas 3D admitidas y devuelve el informe JSON de val3dity.

dataset_id, verbose

cityjson_validate

cjval + val3dity

Ejecuta ambos validadores simultáneamente y devuelve un resultado combinado.

dataset_id

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:

  1. cityjson_clean_vertices

  2. cityjson_validate_schema

  3. opcionalmente 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

cityjson_subset

cjio

Seleccionar/excluir CityObjects por IDs, bbox, radio, recuento aleatorio y/o tipos de CityObject.

ids, bbox, radius, random, types, exclude

cityjson_filter_lod

cjio

Conservar un LoD.

lod

cityjson_reproject

cjio

Transformar coordenadas a un CRS EPSG de destino.

epsg, digit opcional

cityjson_assign_crs

cjio

Asignar una referencia EPSG sin cambiar las coordenadas.

epsg

cityjson_translate

cjio

Trasladar el origen de coordenadas, opcionalmente usando XYZ mínimos explícitos.

minxyz opcional

cityjson_clean_vertices

cjio

Eliminar vértices duplicados y huérfanos.

dataset_id

cityjson_triangulate

cjio

Triangular superficies.

sloppy

cityjson_merge

cjio

Fusionar dos o más conjuntos de datos abiertos.

dataset_ids

cityjson_attribute_rename

cjio

Renombrar un atributo de CityObject en todo el modelo.

old_name, new_name

cityjson_attribute_remove

cjio

Eliminar un atributo de todos los CityObjects.

name

cityjson_remove_textures

cjio

Eliminar información de texturas.

dataset_id

cityjson_remove_materials

cjio

Eliminar información de materiales.

dataset_id

cityjson_upgrade

cjio

Actualizar una versión anterior de CityJSON compatible con el cjio instalado.

dataset_id

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

cityjson_export

cjio

Exportar a CityJSONSeq/JSONL, OBJ, STL, GLB o B3DM.

dataset_id, format, destination, sloppy

citygml_to_cityjson

citygml-tools

Convertir GML/XML de CityGML a CityJSON o CityJSONSeq; la salida CityJSON normal se abre automáticamente.

source, json_lines

cityjson_to_citygml

citygml-tools

Convertir un modelo CityJSON abierto a CityGML.

dataset_id, crs_name opcional, output_directory

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

cityjson_db_import

cjio + cjdb + PostGIS

Convierte CityJSON normal a CityJSONSeq y luego lo importa en un esquema PostgreSQL/PostGIS.

dataset_id, connection, listas de índices opcionales

cityjson_db_export

cjdb + cjio

Exporta un esquema cjdb completo o un conjunto seleccionado de ID de objetos a CityJSONSeq; opcionalmente lo agrupa en un dataset_id CityJSON normal.

connection, query opcional, collect

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

cityjson_spec_outline

índice incluido

Devuelve metadatos de referencia actuales, esquema de capítulos y nombres de esquema conocidos sin acceso a la red.

cityjson_spec_read

especificación canónica de CityJSON

Obtiene el texto de la especificación CityJSON 2.0.2; puede devolver contexto alrededor de una consulta.

cityjson_schema_read

punto final canónico de esquema CityJSON de TU Delft

Obtiene un esquema JSON CityJSON 2.0.2 con nombre como JSON analizado.

cityjson_extensions_registry

registro oficial cityjson/extensions

Recupera el registro, opcionalmente alrededor de un término de búsqueda.

cityjson_extension_schema

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.json con cityjson_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_importcityjson_info.

Validar y diagnosticar

Importa tile.city.json y luego valídalo con cjval y val3dity. 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_importcityjson_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 con cityjson_download como tile-clean.city.json. Nunca sobrescribas el original.

Herramientas esperadas: cityjson_importcityjson_validate_schemacityjson_clean_verticescityjson_validatecityjson_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 con cityjson_download como extract.city.json.

Herramientas esperadas: cityjson_importcityjson_subsetcityjson_filter_lodcityjson_reprojectcityjson_validatecityjson_save.

Interoperabilidad con CityGML

Convierte /input/source.gml a 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_cityjsoncityjson_infocityjson_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 PostgreSQL localhost, base de datos cityjson, esquema municipality. Añade un índice de atributos para yearOfConstruction. Usa la contraseña de la base de datos del entorno del proceso MCP.

Herramientas esperadas: cityjson_importcityjson_validate_schemacityjson_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_infocityjson_extensions_registrycityjson_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_import copia un archivo de la bandeja de entrada al espacio de trabajo gestionado, lo valida y devuelve el ID de conjunto de datos inicial.

  • cityjson_open registra una ruta visible por el servidor explícitamente autorizada para flujos de trabajo avanzados.

  • cityjson_import_text es un recurso alternativo para documentos pequeños; su alias obsoleto cityjson_upload no 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_id aleatorio.

  • cityjson_save es 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:

  1. Raíces permitidas — las operaciones de rutas del host deben estar dentro de CITYJSON_MCP_ALLOWED_ROOTS, CITYJSON_MCP_INPUT o el espacio de trabajo gestionado. Las subidas desde el navegador reciben nombres de archivo aleatorios y seguros dentro del directorio de entrada.

  2. Sin herramienta de shell arbitraria — no hay comando run_shell ni herramienta MCP run_cjio sin restricciones.

  3. Sin interpolación de shell — los programas externos se invocan con matrices de argumentos y shell: false.

  4. Esquemas de herramientas tipados — Zod restringe tipos, enumeraciones, enteros EPSG, formas de bbox, identificadores de esquema de base de datos, etc.

  5. La contraseña de PostgreSQL permanece en el entorno — los esquemas de herramientas de base de datos no contienen un campo de contraseña.

  6. 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.

  7. 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_MS para 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

  • cjio

  • cjdb

  • cjval

  • val3dity

  • citygml-tools

La mayoría de los usuarios deberían extraer la imagen publicada:

docker pull yarroudh/cityjson-mcp:latest

Para 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: yarroudh

  • Secreto 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.0

Una 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 -d

Consulta 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.py

El 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 test

Prueban:

  • 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 check

Los 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_open nativamente 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_query calcula 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_read y las herramientas de registro/esquema de extensiones necesitan acceso de red saliente a los endpoints canónicos de CityJSON. cityjson_spec_outline funciona con el índice incluido.

  • cityjson_to_citygml deja deliberadamente la selección de la versión de CityGML de destino a los valores predeterminados de citygml-tools instalado, en lugar de depender de una marca de CLI no verificada.

  • val3dity es 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


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.

-
license - not tested
Not graded
quality - not tested
B
maintenance

Maintenance

0Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Yarroudh/cityjson-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server