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.
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.
This server cannot be installed
Maintenance
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
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
Query, join, profile, clean and convert CSV/JSON/Parquet with server-side DuckDB over MCP.
Hosted MCP server for AI-driven data ops. Create apps, manage schemas, and CRUD structured data.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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