-
Notifications
You must be signed in to change notification settings - Fork 0
Installation
This page covers every supported way to install CityJSON MCP and Datum. It also explains model configuration, storage, MCP client setup, optional database support, verification, updates, removal, and common installation failures.
| Goal | Recommended path | What is installed on the host |
|---|---|---|
| Use Datum with all 37 tools | Docker with npm run chat
|
Git, Node.js, and Docker |
| Use the MCP server in another AI client | Published Docker image | Docker |
| Develop the interface while using the complete backend image | Docker with repository source mounts | Git, Node.js, and Docker |
| Run every component directly on the host | Manual installation | Node.js, Python, Rust, Java, CMake, and every backend |
| Inspect the interface while some backends are absent | Partial backend host mode | Node.js and any backends being tested |
Docker is recommended for normal use. The image contains compatible backend versions and avoids host language and library conflicts.
The current image contains:
| Component | Image version or source | Purpose |
|---|---|---|
| Node.js | Node 22 runtime | MCP server and Datum server |
| cjio | 0.10.1 |
Transformations, subsets, export, upgrade, and CityJSON sequence conversion |
| cjval | Built with Cargo and the binary feature | CityJSON schema and structure validation |
| val3dity | 2.6.0 |
Three dimensional geometry validation |
| CityGML Tools | 2.5.0 |
CityGML and CityJSON conversion |
| cjdb | 2.3.0 |
PostgreSQL and PostGIS import and export |
| Java | OpenJDK 17 runtime | CityGML Tools runtime |
The project keeps cjio and cjdb in separate Python environments because their dependency requirements differ.
Install:
- Git.
- Node.js version 20 or newer.
- Docker Desktop on macOS or Windows, or Docker Engine with the Compose plugin on Linux.
Start Docker before continuing. Verify the command line tools:
git --version
node --version
npm --version
docker version
docker compose versiongit clone https://github.com/Yarroudh/cityjson-mcp.git
cd cityjson-mcp
npm installnpm install installs the browser dependencies and scripts used by the launcher. It does not install the CityJSON backends on the host.
cp .env.example .envOn Windows PowerShell:
Copy-Item .env.example .envDo not commit .env. It can contain model and database credentials.
Datum requires a language model that supports tool calls. The MCP server can run without a separate model when it is connected directly to an AI client.
Create an OpenRouter API key, then use:
MODEL_PROVIDER=openrouter
MODEL_NAME=openrouter/free
MODEL_API_KEY=replace-with-your-key
MODEL_BASE_URL=https://openrouter.ai/api/v1
MODEL_MAX_OUTPUT_TOKENS=4096
MODEL_TEMPERATURE=0.1
CHAT_ENABLE_OLLAMA=falseopenrouter/free is the recommended free cloud starting point. Capacity and request quotas can vary because free endpoints are shared.
Use this mode for OpenAI and services that expose an OpenAI Chat Completions compatible endpoint:
MODEL_PROVIDER=openai
MODEL_NAME=provider-model-id
MODEL_API_KEY=replace-with-your-key
MODEL_BASE_URL=https://provider.example/v1
MODEL_MAX_OUTPUT_TOKENS=4096
MODEL_TEMPERATURE=0.1
CHAT_ENABLE_OLLAMA=falseUse the exact model identifier and base URL from the provider. The model must support function or tool calls.
MODEL_PROVIDER=anthropic
MODEL_NAME=provider-model-id
MODEL_API_KEY=replace-with-your-key
MODEL_BASE_URL=https://api.anthropic.com
MODEL_MAX_OUTPUT_TOKENS=4096
MODEL_TEMPERATURE=0.1
CHAT_ENABLE_OLLAMA=falseDatum uses the native Anthropic Messages format for this provider.
MODEL_PROVIDER=ollama
MODEL_NAME=qwen3:8b
MODEL_API_KEY=
MODEL_BASE_URL=http://ollama:11434/v1
OLLAMA_BASE_URL=http://ollama:11434/v1
OLLAMA_CONTEXT_LENGTH=16384
CHAT_ENABLE_OLLAMA=trueThe launcher starts the bundled Ollama container when Ollama is selected. The model files are stored in the ollama-models Docker volume. Choose a model that advertises tool support.
Install Ollama, start the application, and pull a tool capable model:
ollama pull qwen3:8b
curl http://127.0.0.1:11434/api/tagsWhen npm run chat detects native Ollama on macOS, it connects the Datum container through host.docker.internal. Native Ollama is preferred on macOS because Docker Desktop does not provide GPU access to its Linux containers.
npm run chatOpen http://127.0.0.1:3000.
The launcher:
- Reads
.env. - Decides whether Ollama is required.
- Uses native Ollama on macOS when it is enabled and reachable.
- Pulls missing container images.
- Starts the Datum service and optional Ollama service without building images.
Useful commands:
npm run chat:logs
npm run chat:stopForce Ollama on or off for one start:
npm run chat -- --with-ollama
npm run chat -- --without-ollamaCommand options take precedence over CHAT_ENABLE_OLLAMA, which takes precedence over automatic selection from MODEL_PROVIDER.
Check the backend bundle inside the image:
docker run --rm --entrypoint node yarroudh/cityjson-mcp:latest /app/scripts/doctor.mjsThe result should report OK for cjio, cjval, val3dity, CityGML Tools, and cjdb.
In Datum:
- Confirm the model appears in the model menu.
- Import
examples/minimal.city.jsonthrough the browser. - Ask for a dataset summary.
- Open the CityJSON MCP catalog and confirm 37 tools.
- Open the viewer.
- Ask Datum to validate the dataset.
The Compose project uses three volumes:
| Volume | Contents |
|---|---|
cityjson-input |
Browser uploads and MCP inbox files |
cityjson-data |
Managed source files, derived datasets, reports, and the dataset registry |
ollama-models |
Downloaded Ollama models |
npm run chat:stop stops the containers without deleting these volumes.
Datum binds only to 127.0.0.1:3000 by default. Ollama is not published on a host port when the bundled container is used. The Compose network allows Datum to reach it internally.
Remote URL import and the live specification, schema, and extension tools require outbound HTTPS access from the MCP process. Local inspection, transformation, and bundled schema outline tools do not require that network access.
To inspect the running services:
docker compose -f docker/docker-compose.chat.yml ps
docker compose -f docker/docker-compose.chat.yml logs cityjson-chatBuild locally when testing backend changes or when the published image is unavailable:
npm run docker:cache:val3dity
npm run docker:cache:cjval
npm run docker:build
npm run docker:doctorThe separate cache commands preserve the expensive compiler stages. The final image is tagged yarroudh/cityjson-mcp:latest.
Use another tag by setting:
CITYJSON_MCP_IMAGE=your-registry/cityjson-mcp:tagThe Dockerfile accepts build arguments for val3dity, CityGML Tools, and compiler job counts. Changing versions can create compatibility differences from the tested image.
Datum is optional. Claude Desktop, Claude Code, Cursor, VS Code, and other clients can start the published image as a standard input and output MCP server.
docker pull yarroudh/cityjson-mcp:latest
docker run --rm --entrypoint node yarroudh/cityjson-mcp:latest /app/scripts/doctor.mjsdocker run --rm -i yarroudh/cityjson-mcp:latest
The -i option is required because MCP communication uses standard input and output. Do not add a terminal allocation option.
Create a folder for CityJSON files and use its absolute path:
{
"mcpServers": {
"cityjson": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--mount",
"type=bind,source=/absolute/path/to/cityjson-files,target=/input,readonly",
"--mount",
"type=volume,source=cityjson-mcp-data,target=/data",
"--env",
"CITYJSON_MCP_ALLOWED_ROOTS=/input:/data",
"--env",
"CITYJSON_MCP_INPUT=/input",
"--env",
"CITYJSON_MCP_WORKSPACE=/data/.cityjson-mcp-workspace",
"yarroudh/cityjson-mcp:latest"
]
}
}
}The host folder is read only in this example. Derived datasets are stored in the Docker volume mounted at /data.
Add another bind mount at /output and include it in CITYJSON_MCP_ALLOWED_ROOTS when tools must save directly into a host folder. Do not remove the read only option from an input folder unless writes are intentional.
On Windows, JSON strings must escape backslashes. Forward slash paths such as C:/CityJSON/input are often easier to read in client configuration.
Files created in an AI client sandbox do not automatically exist inside the MCP container. Copy the file into the mounted inbox, then call cityjson_import with its filename.
| Client | Repository template | Typical destination |
|---|---|---|
| Claude Desktop on macOS | config/claude-desktop.json |
~/Library/Application Support/Claude/claude_desktop_config.json |
| Claude Desktop on Windows | config/claude-desktop.json |
%APPDATA%\Claude\claude_desktop_config.json |
| Claude Code | config/claude-code.json |
.mcp.json in the project |
| Cursor | config/cursor-mcp.json |
.cursor/mcp.json or ~/.cursor/mcp.json
|
| VS Code | config/vscode-mcp.json |
.vscode/mcp.json |
Merge the CityJSON server entry into an existing configuration instead of replacing unrelated servers. Restart or reconnect the MCP server after changing the file.
Manual host mode is intended for development. The complete Docker image is easier to reproduce and support.
Install:
- Node.js 20 or newer.
- Python 3 with virtual environment support.
- Rust and Cargo for cjval.
- Java 17 or newer for CityGML Tools.
- CMake and a C++ compiler for val3dity when a package is unavailable.
- Git and curl.
- PostgreSQL with PostGIS only when database tools are needed.
Clone the project and install JavaScript dependencies:
git clone https://github.com/Yarroudh/cityjson-mcp.git
cd cityjson-mcp
npm install
cp .env.example .envThe Python examples below use macOS and Linux activation commands. In Windows PowerShell, create an environment with py -m venv NAME, activate it with NAME\Scripts\Activate.ps1, and use the executable under NAME\Scripts in .env.
The tested host equivalent is cjio 0.10.1 with export, reprojection, and triangulation dependencies:
python3 -m venv .venv-cjio
source .venv-cjio/bin/activate
python -m pip install --upgrade pip
python -m pip install "cjio==0.10.1" pandas mapbox-earcut pyproj "triangle @ git+https://github.com/drufat/triangle.git@595b43eb6682992a0b1012b9671bf860c0e6ae56"
deactivateSet the executable path in .env:
CJIO_BIN=/absolute/path/to/cityjson-mcp/.venv-cjio/bin/cjioThe explicit triangle source revision matches the Docker image and enables triangulation where a packaged wheel is unavailable. It requires Git and a working native compiler toolchain.
Do not install cjdb into the cjio environment. The tested cjdb release requires an older cjio dependency range.
python3 -m venv .venv-cjdb
source .venv-cjdb/bin/activate
python -m pip install --upgrade pip
python -m pip install "cjdb==2.3.0"
deactivateCJDB_BIN=/absolute/path/to/cityjson-mcp/.venv-cjdb/bin/cjdbThe official cjdb project also recommends an isolated Python environment.
Install Rust, then build the command line binary:
cargo install cjval --features build-binary
cjval --helpIf Cargo binaries are not on PATH, set:
CJVAL_BIN=/absolute/path/to/.cargo/bin/cjvalOn macOS with Homebrew:
brew tap tudelft3d/software
brew install val3dity
val3dity --versionOn Linux, install a C++ compiler, CMake, Eigen, GEOS, CGAL, and Boost filesystem and program options. A Debian or Ubuntu example is:
sudo apt update
sudo apt install build-essential cmake git libcgal-dev libeigen3-dev libgeos++-dev libboost-filesystem-dev libboost-program-options-dev
git clone --depth 1 --branch 2.6.0 https://github.com/tudelft3d/val3dity.git
cmake -S val3dity -B val3dity/build -DCMAKE_BUILD_TYPE=Release
cmake --build val3dity/build --parallelThen set:
VAL3DITY_BIN=/absolute/path/to/val3dity/build/val3dityWindows users can use the executable published by the val3dity project or compile with CMake and its required libraries.
Install Java 17 or newer. Download and extract the CityGML Tools release for version 2.5.0, then verify its launcher:
/absolute/path/to/citygml-tools-2.5.0/citygml-tools --versionSet:
CITYGML_TOOLS_BIN=/absolute/path/to/citygml-tools-2.5.0/citygml-toolsOn Windows, use the launcher supplied in the extracted distribution and enter its absolute path.
Use absolute paths for production use:
CITYJSON_MCP_INPUT=/absolute/path/to/cityjson-input
CITYJSON_MCP_WORKSPACE=/absolute/path/to/cityjson-workspace
CITYJSON_MCP_ALLOWED_ROOTS=/absolute/path/to/cityjson-input:/absolute/path/to/cityjson-outputmacOS and Linux separate allowed roots with a colon. Windows separates them with a semicolon.
npm run doctor
npm test
npm run checkThe doctor script checks:
cjio --version
cjval --help
val3dity --version
citygml-tools --version
cjdb --help
Start the MCP server alone:
npm startStart Datum directly:
npm run chat:hostDatum requires the complete backend bundle by default. For interface inspection during development only:
CHAT_ALLOW_PARTIAL_BACKENDS=trueTools whose backends are missing will still fail.
The database tools are optional. They require a PostgreSQL database with the PostGIS extension and a user with suitable schema permissions.
A typical database preparation is:
createdb cityjson
psql -d cityjson -c 'CREATE EXTENSION IF NOT EXISTS postgis;'Set the password in the Datum or MCP server environment:
PGPASSWORD=replace-with-database-passwordDo not pass a password in MCP tool arguments. Database tool parameters contain the host, user, database, and schema only.
When Datum runs in Docker and PostgreSQL runs on the host, use host.docker.internal as the database host. Ensure PostgreSQL accepts a connection from Docker and use a restricted database role.
| Variable | Default | Purpose |
|---|---|---|
MODEL_PROVIDER |
anthropic |
Default model service: ollama, openrouter, openai, or anthropic
|
MODEL_NAME |
none | Exact default model identifier |
MODEL_API_KEY |
none | Default model credential |
MODEL_BASE_URL |
provider default | Provider API base URL |
MODEL_MAX_OUTPUT_TOKENS |
4096 |
Maximum output tokens per model call |
MODEL_TEMPERATURE |
0.1 |
Sampling temperature from zero to one |
OLLAMA_BASE_URL |
http://127.0.0.1:11434/v1 |
Ollama API URL outside Compose overrides |
OLLAMA_CONTEXT_LENGTH |
16384 |
Ollama context size in tokens |
CHAT_ENABLE_OLLAMA |
automatic | Persistent bundled or native Ollama selection |
CHAT_HOST |
127.0.0.1 |
Datum bind address in host mode |
CHAT_PORT |
3000 |
Datum port |
CHAT_MAX_UPLOAD_BYTES |
1073741824 |
Maximum size of one browser upload request |
CHAT_MAX_UPLOAD_FILES |
5 |
Maximum files in one browser selection |
CHAT_MAX_TOOL_ROUNDS |
12 |
Maximum model and tool rounds per answer |
CHAT_MAX_TOOL_RESULT_CHARS |
100000 |
Maximum tool result characters sent to the model |
CHAT_ALLOW_PARTIAL_BACKENDS |
false |
Permit Datum startup with missing backends for development inspection |
Datum also recognizes OPENROUTER_API_KEY, OPENAI_API_KEY, and ANTHROPIC_API_KEY when the matching provider is selected. MODEL_API_KEY has priority.
| Variable | Default | Purpose |
|---|---|---|
CITYJSON_MCP_ALLOWED_ROOTS |
current directory | Roots allowed for direct file operations |
CITYJSON_MCP_INPUT |
./input |
Inbox used by cityjson_import
|
CITYJSON_MCP_WORKSPACE |
./.cityjson-mcp-workspace |
Managed sources, derived files, reports, and registry |
CITYJSON_MCP_COMMAND_TIMEOUT_MS |
120000 |
External command timeout |
CITYJSON_MCP_MAX_UPLOAD_BYTES |
25 MiB | Limit for inline cityjson_import_text content |
CITYJSON_MCP_MAX_DOWNLOAD_BYTES |
25 MiB | Standalone inline download limit |
CJIO_BIN |
cjio |
cjio executable or absolute path |
CJVAL_BIN |
cjval |
cjval executable or absolute path |
VAL3DITY_BIN |
val3dity |
val3dity executable or absolute path |
CITYGML_TOOLS_BIN |
citygml-tools |
CityGML Tools executable or absolute path |
CJDB_BIN |
cjdb |
cjdb executable or absolute path |
PGPASSWORD |
not set | PostgreSQL password used by cjdb |
CITYJSON_MCP_IMAGE |
yarroudh/cityjson-mcp:latest |
Docker image used by the chat launcher |
OLLAMA_IMAGE |
ollama/ollama:latest |
Bundled Ollama image |
git pull
npm install
docker pull yarroudh/cityjson-mcp:latest
npm run chat:stop
npm run chatThe named volumes remain intact.
Pull source changes, install updated JavaScript packages, rebuild the image, run the doctor command, then restart Datum:
git pull
npm install
npm run docker:build
npm run docker:doctor
npm run chat:stop
npm run chatRun npm install, review Dockerfile version changes, update each isolated backend environment deliberately, then run npm run doctor, npm test, and npm run check.
Stop Datum without deleting data:
npm run chat:stopRemove only the pulled images when they are no longer needed:
docker image rm yarroudh/cityjson-mcp:latest
docker image rm ollama/ollama:latestDocker volumes contain imported files, derived datasets, and Ollama models. Removing volumes permanently deletes that data. Inspect them before any removal:
docker volume lsFor a manual host installation, remove the project folder and the isolated Python environments only after saving any needed files from the configured input and workspace directories.
An error under /var/lib/docker or /var/lib/desktop-containerd concerns Docker Desktop storage, not the project directory. Quit and restart Docker Desktop, check available disk space, and run docker info. If Docker remains read only, use Docker Desktop diagnostics. A Docker factory reset deletes local images, containers, and volumes and should be a final recovery step.
Start Docker Desktop or the Docker daemon. Confirm both docker version and docker compose version work in the same terminal used for npm run chat.
Check network access, Docker registry access, disk space, and the image name. Build locally with npm run docker:build when the source is available.
Stop the process using the port or change CHAT_PORT for direct host mode. The current Compose file publishes port 3000 explicitly, so changing the Compose port mapping is required for Docker mode.
Verify that provider, key, model identifier, and base URL belong to the same service. A correct key can still receive quota, billing, capacity, or rate limit errors. Datum accepts a model only after a live tool call test succeeds.
For bundled Ollama, use http://ollama:11434/v1 inside Compose. For direct host mode, use http://127.0.0.1:11434/v1. On macOS, start the native Ollama application before npm run chat when native acceleration is desired.
Confirm that the file is inside the host folder mounted at /input. Call cityjson_list_imports, then call cityjson_import with the filename only. Host paths and AI client sandbox paths do not automatically exist in the container.
Run npm run doctor in host mode or the image doctor command in Docker mode. Set the matching executable override to an absolute path. The backend status tool reports availability without changing files.
Confirm Java 17 or newer and execute the launcher directly with its version option. Check file execution permission on macOS and Linux.
Confirm PostgreSQL network access, PostGIS installation, database permissions, PGPASSWORD, and the database host visible from the Datum environment.
Restart Datum and refresh the page. Application assets use versioned URLs and are served without persistent caching, but an older running container can still serve older source.
- Docker installation
- Node.js downloads
- Ollama downloads
- cjio repository and installation
- cjval repository and installation
- val3dity repository and installation
- CityGML Tools repository and installation
- cjdb repository and installation
- Open the Datum guide for the complete interface workflow.
- Review the 37 MCP tools.
- Return to the Wiki Home.