cityjson-mcp
CityJSON MCP
사양을 읽기만 하는 것이 아니라 CityJSON으로 실제 작업을 수행하기 위한 로컬 Model Context Protocol(MCP) 서버입니다.
Claude Desktop, Cursor, VS Code와 같은 MCP 클라이언트에 다음을 기반으로 하는 안정적인 CityJSON 지향 도구 API를 제공합니다:
cjio — CityJSON 조작, 필터링, CRS 연산, 정리, 병합 및 내보내기.
cjval — 공식 CityJSON/CityJSONSeq 구문, 스키마 및 구조 검증.
val3dity — CityJSON 프리미티브에 대한 3D 기하학적 유효성 검사.
citygml-tools — CityGML ↔ CityJSON 변환.
cjdb + PostgreSQL/PostGIS — 영구 CityJSON 저장/가져오기/내보내기.
CityJSON 2.0.2 사양, JSON 스키마 및 확장 레지스트리 — 에이전트를 위한 실시간 표준 참조 접근.
서버는 38개의 MCP 도구를 노출합니다. 변환은 불변 데이터셋 핸들을 사용합니다: cityjson_subset과 같은 연산은 새 dataset_id를 반환하며 소스 데이터셋을 덮어쓰지 않습니다. 선택적 단일 페이지 채팅 호스트는 브라우저 첨부 파일을 MCP 입력 받은 편지함으로 스트리밍하고 구성된 모델에는 데이터셋 핸들만 전송합니다.
상태: 실용적인 v0.1 구현입니다. 권장 Docker 이미지는 모든 외부 백엔드를 번들로 포함합니다. Docker 없이 개발하려면 개별 명령을 별도로 설치해야 합니다.
아키텍처
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 --> KNOWMCP 지향 API는 의도적으로 run_cjio("...")와 같은 임의의 셸 명령을 노출하지 않습니다. 각 MCP 도구에는 타입이 지정된 입력 스키마가 있습니다. 명령은 spawn(..., { shell: false })로 호출되어 에이전트 지향 계약을 안정적으로 유지하고 셸 문자열 보간을 피합니다.
일반적인 에이전트 워크플로우
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사용자는 예를 들어 다음과 같이 말할 수 있습니다:
rotterdam.city.json을 가져와서 CityJSON 구조와 3D 기하학을 모두 검증하고, bbox[90000, 435000, 91000, 436000]내부의 건물만 유지한 다음, 결과를 EPSG:28992로 재투영하고, 중복 및 고아 정점을 정리한 후, 결과를 다시 검증하고cityjson_download로 반환하세요.
MCP 클라이언트는 이 요청을 대략 다음과 같이 처리할 수 있습니다:
cityjson_importcityjson_validatecityjson_subsetcityjson_reprojectcityjson_clean_verticescityjson_validatecityjson_save
각 변환은 새 dataset_id를 반환하므로 대화 중에도 중간 상태를 계속 사용할 수 있습니다.
빠른 시작
첨부 파일을 직접 처리하는 DATUM 단일 페이지 채팅
포함된 DATUM 채팅 애플리케이션은 가장 간단한 첨부 파일 워크플로우입니다. 각 브라우저 첨부 파일을 CITYJSON_MCP_INPUT으로 스트리밍하고, 라이브 MCP 서버를 통해 가져온 다음, 모델에는 결과 dataset_id와 요약만 제공합니다.
로컬 환경 파일에서 기본 모델을 선택적으로 사전 구성할 수 있습니다:
cp .env.example .envAPI 스타일을 선택한 다음 도구 지원 모델 ID, 키 및 기본 URL을 설정합니다. 예를 들어 DeepSeek는 OpenAI 호환 스타일을 사용합니다:
MODEL_PROVIDER=openai
MODEL_NAME=deepseek-v4-pro
MODEL_API_KEY=your-api-key
MODEL_BASE_URL=https://api.deepseek.com이 파일은 선택 사항입니다: 모델, 공급자, API 키 및 기본 URL은 애플리케이션의 모델 구성 대화상자에서도 입력할 수 있습니다. 대화상자 자격 증명은 브라우저 세션 동안 서버 메모리에만 보관되며 브라우저로 반환되거나 MCP 도구에 전달되지 않습니다.
MODEL_PROVIDER는 anthropic 또는 openai를 허용합니다. 이는 모델을 제공하는 회사가 아니라 API 프로토콜을 선택하기 때문입니다. anthropic은 Messages를 사용하고, openai는 OpenAI 호환 Chat Completions를 사용하므로 MODEL_BASE_URL을 통해 DeepSeek과 같은 호환 서비스도 지원합니다.
전체 애플리케이션을 실행합니다. 이미지에 cjio, cjval, val3dity, citygml-tools 및 cjdb가 포함되어 있으므로 이것이 기본값입니다:
npm install
npm run chat그런 다음 http://127.0.0.1:3000을 엽니다. 파일을 첨부하면 다음 시퀀스가 자동으로 수행됩니다:
browser multipart stream → input inbox → cityjson_import → dataset_id → model tool loopnpm run chat은 다음 명령과 동일합니다:
docker compose -f docker/docker-compose.chat.yml up --buildCompose 구성은 애플리케이션을 127.0.0.1에만 바인딩하고 입력/작업 공간 데이터를 Docker 볼륨에 유지합니다. .env에서 선택적 기본 모델을 읽습니다. 그렇지 않으면 애플리케이션이 모델 구성 대화상자를 엽니다.
다섯 개의 실행 파일이 모두 설치된 호스트에서 개발하려면 npm run chat:host를 사용하세요. 호스트 모드는 백엔드 준비 상태 검사를 수행하고 기능하지 않는 도구 상자를 광고하지 않습니다. CHAT_ALLOW_PARTIAL_BACKENDS=true는 의도적인 검사 전용 개발의 경우에만 해당 검사를 재정의합니다.
완전한 Docker 런타임을 사용하는 독립형 MCP 클라이언트
Docker 이미지에는 MCP 서버와 다섯 개의 백엔드가 모두 포함되어 있습니다. Docker Desktop을 설치한 다음 Docker Hub에서 이미지를 가져옵니다:
docker pull yarroudh/cityjson-mcp:latest모든 백엔드가 있는지 확인합니다:
docker run --rm --entrypoint node yarroudh/cityjson-mcp:latest /app/scripts/doctor.mjs출력에는 cjio, cjval, val3dity, citygml-tools 및 cjdb에 대해 OK가 보고되어야 합니다.
입력 받은 편지함 구성
MCP 자체는 일반 채팅 첨부 파일을 전송하지 않습니다. Claude Desktop 및 기타 독립형 클라이언트의 경우 호스트 디렉터리를 한 번 마운트합니다. /absolute/path/to/cityjson-files를 실제 절대 디렉터리로 바꾸세요:
{
"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"
]
}
}
}호스트 디렉터리는 Docker 내부에서 /input으로 표시됩니다. 사용자와 에이전트는 파일 이름만 참조합니다:
model.city.json을 가져와서 요약하세요.
에이전트는 cityjson_import({"filename":"model.city.json"})를 호출합니다. cityjson_list_imports는 사용 가능한 파일 이름을 찾을 수 있고, cityjson_import는 선택한 소스를 불변 관리 작업 공간으로 복사합니다. 입력 마운트는 수정할 수 없습니다.
/mnt/user-data/... 및 /home/claude/...와 같은 채팅 첨부 파일 경로는 클라이언트의 개인 환경에 속합니다. MCP 컨테이너 내부에는 존재하지 않습니다. cityjson_import_text는 프로그래밍 방식으로 제공된 작은 JSON 텍스트에만 계속 사용할 수 있습니다. cityjson_upload는 더 이상 사용되지 않는 호환 별칭이며 실제 파일 업로드 채널이 아닙니다.
이미지에는 cjio, cjval, val3dity, citygml-tools 및 cjdb가 포함되어 있습니다. 호스트 Python, Rust, Java 또는 지리공간 라이브러리가 필요하지 않습니다. docker pull yarroudh/cityjson-mcp:latest를 다시 실행하면 Docker가 필요할 때 최신 이미지 레이어를 자동으로 가져옵니다.
소스에서 빌드하려면 나머지 이미지를 빌드하기 전에 두 개의 느린 컴파일 단계를 캐시하세요:
npm install
npm run docker:cache:val3dity
npm run docker:cache:cjval
npm run docker:build
npm run docker:doctor이후 레이어가 실패하면 최종 명령을 다시 실행하면 val3dity 및 cjval 레이어를 처음부터 컴파일하는 대신 완성된 레이어를 재사용합니다.
선택 사항: Docker 없이 실행
다음 섹션은 완전한 Docker 이미지 대신 node src/index.mjs를 직접 실행할 때만 필요합니다.
1. 요구 사항
MCP 서버 자체에는 다음이 필요합니다:
Node.js 20 이상
npm
JavaScript 종속성을 설치합니다:
cd cityjson-mcp
npm install그런 다음 소스 및 네이티브 테스트를 확인합니다:
npm run check
npm test사용 가능한 외부 백엔드를 확인합니다:
npm run doctor일부 백엔드가 없어도 MCP는 시작할 수 있습니다. 누락된 백엔드에 의존하는 도구만 실패합니다. 에이전트는 cityjson_backend_status를 직접 호출할 수도 있습니다.
2. 필요한 백엔드 설치
cjio
공식 프로젝트: https://github.com/cityjson/cjio
python -m pip install 'cjio[export,reproject,validate]'재투영, 삼각 측량/내보내기 및 관련 연산에 선택적 Python 패키지가 필요하므로 extras가 유용합니다.
cjval
공식 프로젝트: https://github.com/cityjson/cjval
Rust를 설치한 다음:
cargo install cjval --features build-binaryval3dity
공식 프로젝트: https://github.com/tudelft3d/val3dity
macOS에서는 업스트림 프로젝트가 Homebrew 포뮬러를 제공합니다:
brew tap tudelft3d/software
brew install val3dityWindows에서는 업스트림 릴리스 실행 파일을 사용합니다. Linux에서는 업스트림 CMake/CGAL/Eigen/GEOS 빌드 지침을 따릅니다. val3dity는 현재 CityJSON/CityJSONSeq를 직접 검증합니다. 최신 릴리스는 더 이상 CityGML을 구문 분석하지 않으므로 소스가 CityGML인 경우 먼저 citygml_to_cityjson을 사용하세요.
citygml-tools
공식 프로젝트: https://github.com/citygml4j/citygml-tools
최신 릴리스에는 Java 17 이상이 필요합니다. 배포판을 다운로드하여 압축을 풀고 citygml-tools 실행 프로그램이 PATH에 있는지 확인하거나 CITYGML_TOOLS_BIN을 실행 프로그램으로 지정하세요. 이 README를 작성할 당시의 현재 안정 릴리스는 2.5.0입니다.
cjdb
공식 프로젝트: https://github.com/cityjson/cjdb
python -m pip install cjdbcjdb에는 PostGIS가 포함된 PostgreSQL이 필요합니다. 개발용 compose 파일은 docker/docker-compose.postgis.yml에 포함되어 있습니다.
3. MCP가 액세스할 수 있는 폴더 승인
서버는 명시적으로 승인된 루트 외부의 파일 경로를 거부합니다.
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는 루트 사이에 세미콜론을 사용합니다:
C:\citydata;D:\city-models작업 공간은 파생 CityJSON 데이터셋, 검증기 보고서 및 중간 CityJSONSeq 파일을 저장합니다. 자동으로 생성됩니다.
선택적 실행 파일 재정의:
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/cjdbcjdb의 경우 MCP 인수에 넣는 대신 프로세스 환경에 PostgreSQL 비밀번호를 설정하세요:
export PGPASSWORD='...'4. 서버 수동 테스트
stdio MCP 서버는 직접 실행하면 stdin에서 MCP JSON-RPC 메시지를 기다리기 때문에 일반적으로 "아무것도 하지 않는" 것처럼 보입니다. 그래도 다음으로 시작을 확인할 수 있습니다:
npm run doctor
npm test그런 다음 아래 MCP 클라이언트 중 하나를 구성합니다. 제공된 템플릿은 완전한 Docker 이미지를 실행합니다. 기여자는 Docker 명령을 node src/index.mjs의 절대 경로로 바꾸고 위의 환경 변수를 설정할 수 있습니다.
Claude Desktop에 추가
Claude Desktop 로컬 MCP 구성은 mcpServers 객체를 사용합니다. 제공된 템플릿은 호스트 마운트 없이 게시된 이미지를 실행합니다. 대용량 파일 작업 시 빠른 시작에 표시된 마운트를 추가하세요.
Claude Desktop 템플릿은 config/claude-desktop.json에 있습니다.
{
"mcpServers": {
"cityjson": {
"command": "docker",
"args": ["run", "--rm", "-i", "yarroudh/cityjson-mcp:latest"]
}
}
}Claude Desktop 로컬 서버의 일반적인 구성 위치는 다음과 같습니다:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
템플릿을 클라이언트 구성에 병합한 다음 Claude Desktop을 완전히 종료하고 다시 엽니다. config/ 디렉터리에는 템플릿이 포함되어 있습니다. Claude가 자동으로 읽지 않습니다.
일반 Claude 채팅에서 **+**를 클릭하고 Connectors를 연 다음 cityjson을 활성화하고 Tool access에서 해당 도구를 허용합니다. 커넥터는 활성화된 채팅에서만 사용할 수 있습니다. /input은 Claude의 코드 환경이 아닌 커넥터 컨테이너 내부에 존재합니다.
macOS에서 도구 사용을 확인하려면:
tail -f "$HOME/Library/Logs/Claude/mcp-server-cityjson.log"성공적인 호출은 method="tools/call" 다음에 서버 결과로 표시됩니다. Ctrl+C를 눌러 감시를 중지합니다.
Claude Desktop은 패키지된 MCP 번들/확장도 지원합니다. 이 저장소는 투명하고 편집 가능하도록 소스 ZIP으로 제공됩니다. 위의 직접 stdio 구성이 가장 간단한 개발 설정입니다.
Claude Code에 추가
Claude Code 템플릿은 config/claude-code.json에 있습니다. Claude Code를 실행하는 프로젝트의 .mcp.json에 복사하세요:
cp config/claude-code.json .mcp.json구성 변경 후 Claude Code를 다시 시작하거나 MCP 서버를 다시 연결하세요.
Cursor에 추가
Cursor는 mcp.json에서 로컬 stdio MCP 서버를 지원합니다.
템플릿은 config/cursor-mcp.json에 포함되어 있습니다.
프로젝트 구성:
your-project/
└── .cursor/
└── mcp.json전역 구성:
~/.cursor/mcp.json예:
{
"mcpServers": {
"cityjson": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "yarroudh/cityjson-mcp:latest"]
}
}
}활성화되면 Cursor가 MCP 도구를 발견하고 자동으로 선택할 수 있습니다. 프롬프트에서 도구 이름을 명시적으로 지정할 수도 있습니다. 예:
이 모델에
cityjson_validate를 사용한 다음 관련된 경우 CityJSON 사양을 사용하여 실패한 모든 val3dity 오류를 설명하세요.
Cursor 문서: https://cursor.com/docs/mcp
VS Code에 추가
VS Code는 최상위 키가 servers인 mcp.json을 사용합니다.
템플릿은 config/vscode-mcp.json에 포함되어 있습니다.
작업 공간 구성:
your-project/
└── .vscode/
└── mcp.json예:
{
"servers": {
"cityjson": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "yarroudh/cityjson-mcp:latest"]
}
}
}명령 팔레트를 열고 MCP 서버 관리 명령을 사용하여 필요한 경우 서버를 검사/시작합니다. VS Code는 지원되는 플랫폼에서 MCP 샌드박스 제어도 지원합니다. 이는 이 서버 자체의 허용 루트 정책 위에 계층화할 수 있습니다.
VS Code 문서: https://code.visualstudio.com/docs/agents/reference/mcp-configuration
클라이언트 설정 모델
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도구 카탈로그
데이터셋 및 진단
도구 | 백엔드 | 용도 | 주요 입력 |
| native |
| 없음 |
| native | 구성된 입력 받은 편지함(inbox)에서 사용 가능한 JSON 파일 이름을 나열합니다. | 없음 |
| native | 파일 이름으로 받은 편지함 파일을 가져오고 변경 불가능한 | 선택적 |
| native | 프로그래밍 방식 클라이언트를 위한 소형 텍스트 대체 수단입니다. 콘텐츠는 MCP JSON을 통해 전달됩니다. |
|
| native | 일반 CityJSON JSON 파일을 열고 |
|
| native |
|
|
| native | 열었거나 변환한 모델을 직접 웹 스트리밍 또는 인라인 MCP 다운로드용으로 준비합니다. |
|
| native | 유형/버전, 객체 수, LoD, 속성, 메타데이터, transform 및 확장을 요약합니다. |
|
| native | 열었거나 파생된 데이터셋을 명시적으로 허용된 경로에 복사합니다. |
|
cityjson_import
채팅 애플리케이션이 입력 받은 편지함에 전달했거나 마운트된 디렉터리에 배치한 파일에 이 도구를 사용하세요:
{
"filename": "amsterdam.city.json"
}파일 이름을 모르는 경우 cityjson_list_imports를 호출하세요. filename을 생략하면 JSON 파일이 정확히 하나만 있을 때 자동으로 가져옵니다. 이 도구는 핸들을 반환하기 전에 소스를 복사하고 검증합니다.
cityjson_import_text
애플리케이션 워크플로에 작은 CityJSON 문서가 이미 텍스트로 존재하는 경우에만 이 도구를 사용하세요:
{
"filename": "model.city.json",
"content": "{\"type\":\"CityJSON\",\"version\":\"2.0\",\"CityObjects\":{},\"vertices\":[]}"
}콘텐츠는 관리형 작업 공간에 기록되기 전에 구조적으로 검사됩니다. 전체 문서가 MCP 요청을 통해 전달되므로 브라우저/채팅 첨부 파일에는 적합하지 않습니다. cityjson_upload는 호환성을 위해 더 이상 사용되지 않는 별칭으로 유지됩니다.
cityjson_open
cityjson_open은 허용된 루트 내부의 서버에서 볼 수 있는 전체 경로를 의도적으로 제공하는 고급 클라이언트를 위해 계속 사용할 수 있습니다. 일반적인 받은 편지함 및 첨부 파일 워크플로는 cityjson_import를 사용해야 합니다.
cityjson_download
호스트 디렉터리가 마운트되지 않은 컨테이너에서 소스 또는 변환된 데이터셋을 검색하려면 이 도구를 사용하세요:
{
"dataset_id": "cj_abc123def456",
"filename": "cleaned.city.json"
}DATUM에서는 호스트가 변경 불가능한 작업 공간 파일을 직접 스트리밍하고 다운로드 버튼을 표시하므로 대용량 결과가 모델 컨텍스트나 MCP JSON을 통과하지 않습니다. 독립형 MCP 클라이언트는 포함된 application/json 리소스를 받습니다. 해당 인라인 경로는 CITYJSON_MCP_MAX_DOWNLOAD_BYTES로 제어되는 25MiB 제한이 기본값입니다.
대표 결과:
{
"datasetId": "cj_4ad572e79331",
"version": "2.0",
"cityObjectCount": 12543,
"vertexCount": 382901,
"lods": ["1.2", "2.2"]
}핸들은 파일을 가리키는 메모리 내 메타데이터입니다. CityJSON 문서 자체는 단순히 여는 것만으로 복사되지 않습니다.
검사 및 쿼리
도구 | 백엔드 | 용도 | 주요 입력 |
| native | ID, 유형, 속성, LoD 및 관계가 포함된 CityObject의 페이지네이션 목록. |
|
| native | 하나의 완전한 CityObject를 반환하고 참조된 정점에서 3D 경계 상자를 계산합니다. |
|
| native | ID, CityObject 유형, 2D 경계 상자 및 속성 조건으로 필터링합니다. |
|
cityjson_query는 전체 CityJSON 문서를 모델 컨텍스트로 보내지 않고 LLM이 대용량 모델을 검사하도록 하는 기본 방법입니다.
예시:
{
"dataset_id": "cj_4ad572e79331",
"types": ["Building", "BuildingPart"],
"bbox": [85000, 446000, 86000, 447000],
"attributes": {
"yearOfConstruction": { "gte": 2000 },
"status": { "in": ["existing", "planned"] }
},
"limit": 100
}속성 조건 연산자:
eqneqgtgteltltecontainsin
경계 상자 필터는 데이터셋 CRS 기준 [minX, minY, maxX, maxY]입니다. 객체 경계 상자는 객체가 참조하는 정점과 CityJSON transform(있는 경우)에서 계산됩니다.
검증
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도구 | 백엔드 | 용도 | 주요 입력 |
| cjval | 공식 CityJSON 구문/스키마 및 구조적 일관성 검증. |
|
| val3dity | 지원되는 3D 프리미티브를 검증하고 val3dity JSON 보고서를 반환합니다. |
|
| cjval + val3dity | 두 검증기를 동시에 실행하고 하나의 결합된 결과를 반환합니다. |
|
어떤 검증기를 언제 사용할까
다음과 같은 질문에는 cityjson_validate_schema를 사용하세요:
JSON이 구문적으로 유효한 CityJSON인가?
CityJSON 스키마를 준수하는가?
부모/자식 참조가 일관적인가?
정점 인덱스가 존재하는가?
의미론/재질/텍스처 배열이 구조적으로 일관적인가?
확장 스키마가 유효한가?
MultiSurface, CompositeSurface, Solid, MultiSolid, CompositeSolid 프리미티브의 기하학적 유효성 및 관련 CityJSON 고유 기하학 검사에는 cityjson_validate_geometry를 사용하세요.
일반 사용자 요청인 "이 CityJSON 검증"에는 **cityjson_validate**를 사용하세요.
예시:
{
"dataset_id": "cj_4ad572e79331"
}cjval 경고가 중복 또는 사용되지 않는 정점을 보고하는 경우 자연스러운 복구 루프는 다음과 같습니다:
cityjson_clean_verticescityjson_validate_schema선택적으로
cityjson_validate_geometry
변환 및 조작
이 섹션의 모든 도구는 새 데이터셋 핸들을 반환합니다.
도구 | 백엔드 | 용도 | 중요 입력 |
| cjio | ID, 경계 상자, 반경, 무작위 개수 및/또는 CityObject 유형으로 CityObject를 선택/제외합니다. |
|
| cjio | 하나의 LoD를 유지합니다. |
|
| cjio | 좌표를 대상 EPSG CRS로 변환합니다. |
|
| cjio | 좌표를 변경하지 않고 EPSG 참조를 할당합니다. |
|
| cjio | 선택적으로 명시적 최소 XYZ를 사용하여 좌표 원점을 이동합니다. | 선택적 |
| cjio | 중복 및 고아 정점을 제거합니다. |
|
| cjio | 표면을 삼각분할합니다. |
|
| cjio | 두 개 이상의 열린 데이터셋을 병합합니다. |
|
| cjio | 모델 전체에서 CityObject 속성 이름을 변경합니다. |
|
| cjio | CityObject 전체에서 속성을 제거합니다. |
|
| cjio | 텍스처 정보를 제거합니다. |
|
| cjio | 재질 정보를 제거합니다. |
|
| cjio | 설치된 cjio가 지원하는 이전 CityJSON 버전을 업그레이드합니다. |
|
하위 집합 예시
경계 상자 내 건물:
{
"dataset_id": "cj_4ad572e79331",
"types": ["Building"],
"bbox": [85000, 446000, 86000, 447000]
}특정 객체:
{
"dataset_id": "cj_4ad572e79331",
"ids": ["NL.IMBAG.Pand.001", "NL.IMBAG.Pand.002"]
}식생 객체를 제외한 모든 것:
{
"dataset_id": "cj_4ad572e79331",
"types": ["SolitaryVegetationObject", "PlantCover"],
"exclude": true
}CRS 처리
좌표가 이미 해당 CRS로 표현되어 있고 메타데이터가 누락/잘못된 경우에만 cityjson_assign_crs를 사용하세요. 이 도구는 좌표를 변환하지 않습니다.
좌표를 실제로 변환해야 하는 경우 cityjson_reproject를 사용하세요:
{
"dataset_id": "cj_4ad572e79331",
"epsg": 28992
}안정적인 재투영을 위해 소스 모델에는 사용 가능한 소스 CRS가 필요합니다.
내보내기 및 상호 운용성
도구 | 백엔드 | 용도 | 입력 |
| cjio | CityJSONSeq/JSONL, OBJ, STL, GLB 또는 B3DM으로 내보냅니다. |
|
| citygml-tools | CityGML GML/XML을 CityJSON 또는 CityJSONSeq로 변환합니다. 일반 CityJSON 출력은 자동으로 열립니다. |
|
| citygml-tools | 열린 CityJSON 모델을 CityGML로 변환합니다. |
|
내보내기 예시:
{
"dataset_id": "cj_4ad572e79331",
"format": "glb",
"destination": "/data/buildings.glb"
}CityGML → CityJSON 예시:
{
"source": "/input/model.gml",
"json_lines": false
}CityJSON → CityGML 예시:
{
"dataset_id": "cj_4ad572e79331",
"crs_name": "urn:ogc:def:crs:EPSG::28992",
"output_directory": "/data/citygml-output"
}래퍼는 의도적으로 CityGML/CityJSON 대상 버전 옵션을 임의로 만들지 않습니다. citygml-tools는 CityGML 1.0/2.0/3.0 및 CityJSON 1.0/1.1/2.0을 지원하지만 정확한 대상 버전 CLI 동작은 업스트림 릴리스에 따라 달라질 수 있습니다. 설치된 백엔드의 기본값이 권위 있는 기준입니다.
데이터베이스 도구
도구 | 백엔드 | 용도 | 입력 |
| cjio + cjdb + PostGIS | 일반 CityJSON을 CityJSONSeq로 변환한 후 PostgreSQL/PostGIS 스키마로 가져옵니다. |
|
| cjdb + cjio | 전체 cjdb 스키마 또는 선택한 객체 ID 집합을 CityJSONSeq로 내보냅니다. 선택적으로 일반 CityJSON |
|
연결 객체:
{
"host": "localhost",
"user": "cityjson",
"database": "cityjson",
"schema": "rotterdam"
}가져오기:
{
"dataset_id": "cj_4ad572e79331",
"connection": {
"host": "localhost",
"user": "cityjson",
"database": "cityjson",
"schema": "rotterdam"
},
"attribute_indexes": ["yearOfConstruction"],
"partial_attribute_indexes": ["function"]
}부분 집합 내보내기:
{
"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
}래퍼는 SELECT 이외의 SQL, 세미콜론, 명백한 수정 키워드를 거부합니다. 이는 안전장치일 뿐이며 SQL 보안 경계가 아닙니다: 작업에 적합한 권한만 가진 데이터베이스 역할을 사용하세요. 내보내기의 경우 데이터를 수정할 수 없는 역할을 사용하세요.
사양, 스키마 및 확장 지식
도구 | 소스 | 용도 |
| 번들 인덱스 | 네트워크 접근 없이 현재 참조 메타데이터, 장 개요 및 알려진 스키마 이름을 반환합니다. |
| 표준 CityJSON 사양 | CityJSON 2.0.2 사양 텍스트를 가져옵니다. 쿼리 주변의 컨텍스트를 반환할 수 있습니다. |
| 표준 TU Delft CityJSON 스키마 엔드포인트 | 명명된 CityJSON 2.0.2 JSON Schema를 파싱된 JSON으로 가져옵니다. |
| 공식 | 레지스트리를 검색어 주변에서 검색하여 가져옵니다. |
| 표준 CityJSON 확장 URL | 이름/버전으로 특정 등록 확장 스키마를 가져옵니다. |
사양 조회 예시:
{
"query": "Geometry templates",
"max_chars": 20000
}핵심 스키마 조회 예시:
{
"name": "geomprimitives.schema.json"
}확장 검색 예시:
{
"query": "noise"
}그런 다음 특정 스키마를 가져옵니다:
{
"name": "noise",
"version": "2.0.0"
}이것이 cityjson/cj-mcp에 의존하지 않는 이유
cityjson/cj-mcp는 사양 장 검색에 유용합니다. 이 서버는 더 광범위한 작업이 필요하므로 지식 어댑터가 표준 CityJSON 사양/스키마/확장 소스를 직접 읽고 작은 결정적 2.0.2 참조 인덱스를 번들로 제공합니다. 이렇게 하면 두 번째 MCP 프로세스와 버전 불일치 실패 모드를 피할 수 있습니다.
향후 어댑터는 공개 MCP 도구 이름을 변경하지 않고 cityjson_spec_read를 cj-mcp에 위임할 수 있습니다.
권장 프롬프트 / 레시피
이 프롬프트는 호스트 파일 디렉터리가 입력 받은 편지함으로 구성되어 있다고 가정합니다. 에이전트는 파일 이름을 사용하며 자체 코드 환경에서 /input을 확인하지 않습니다.
수정 전 검사
cityjson_import로tile.city.json을 가져오세요. CityJSON 버전, CRS, 유형별 CityObject 수, LoD, 속성 이름 및 확장을 알려주세요. 아무것도 수정하지 마세요.
예상 도구: cityjson_import → cityjson_info.
검증 및 진단
tile.city.json을 가져온 다음cjval및val3dity로 검증하세요. CityJSON 커넥터 도구만 사용하세요. cjval 경고와 오류를 분리하고, val3dity 오류를 오류 코드별로 그룹화하고, 영향을 받는 CityObject ID를 식별하고, 오류가 CityJSON 구조 규칙에 관한 것이라면 CityJSON 사양을 참조하세요. 검증 보고서가 도구 출력 한도를 초과하면 겹치지 않는 공간 부분 집합을 만들고 각 부분 집합을 검증한 후 이중 계산 없이 개수를 집계하세요. 원본 파일은 수정하지 마세요.
예상 도구: cityjson_import → cityjson_validate → 선택적으로 cityjson_get_object / cityjson_spec_read.
안전한 정리 루프
tile.city.json을 가져오고 구조 검증을 실행한 후, 유일한 구조 경고가 중복되거나 사용되지 않는 정점뿐이라면 정리된 파생 데이터셋을 만들고 전체 검증을 다시 실행한 후cityjson_download로tile-clean.city.json으로 결과를 반환하세요. 원본을 절대 덮어쓰지 마세요.
예상 도구: cityjson_import → cityjson_validate_schema → cityjson_clean_vertices → cityjson_validate → cityjson_save.
공간 추출
받은 편지함 파일
city.city.json에서 bbox[85000, 446000, 86000, 447000]와 교차하는 Building 및 BuildingPart 객체만 추출하고, LoD 2.2를 유지하고, EPSG:28992로 재투영하고, 결과를 검증한 후cityjson_download로extract.city.json으로 반환하세요.
예상 도구: cityjson_import → cityjson_subset → cityjson_filter_lod → cityjson_reproject → cityjson_validate → cityjson_save.
CityGML 상호 운용성
/input/source.gml을 CityJSON으로 변환하고, 결과 객체 유형과 LoD를 검사하고, cjval 및 val3dity로 검증하고, 변환 중 손실되거나 정규화된 정보를 보고하세요.
예상 도구: citygml_to_cityjson → cityjson_info → cityjson_validate, 유용할 때 사양 조회 추가.
데이터베이스 워크플로
받은 편지함 파일
municipality.city.json을 가져와 검증한 다음 PostgreSQL 호스트localhost, 데이터베이스cityjson, 스키마municipality로 가져오세요.yearOfConstruction에 대한 속성 인덱스를 추가하세요. 데이터베이스 비밀번호는 MCP 프로세스 환경에서 사용하세요.
예상 도구: cityjson_import → cityjson_validate_schema → cityjson_db_import.
확장 인식 추론
이 모델은 CityJSON
noise확장을 선언합니다. 등록된 확장 문서/스키마를 찾아 허용하는 추가 속성을 설명하고, 로컬 확장 스키마를 제공하면 그 스키마로 모델을 검증하세요.
예상 도구: cityjson_info → cityjson_extensions_registry → cityjson_extension_schema → 선택적으로 cityjson_validate_schema.
데이터 수명 주기 및 불변성
핵심 설계는 다음과 같습니다:
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는 받은 편지함 파일을 관리형 작업 공간에 복사하고, 검증한 후 초기 데이터셋 ID를 반환합니다.cityjson_open은 고급 워크플로를 위해 명시적으로 승인된 서버 표시 경로를 등록합니다.cityjson_import_text는 소형 문서용 대체 수단입니다. 더 이상 사용되지 않는cityjson_upload별칭은 바이너리 첨부 파일을 처리하지 않습니다.변환은 백엔드에
CITYJSON_MCP_WORKSPACE내부에 새 파일을 쓰도록 요청합니다.서버는 생성된 파일을 열고 새 무작위
dataset_id를 부여합니다.cityjson_save는 선택한 상태를 사용자가 선택한 대상에 복사하는 명시적 단계입니다.
이렇게 하면 에이전트가 검증 전후를 훨씬 쉽게 비교할 수 있고 일반 변환 호출이 원본 소스를 조용히 덮어쓰는 것을 방지할 수 있습니다.
보안 모델
이 서버는 강력한 지리공간 프로그램을 로컬에서 실행합니다. MCP 서버 설치는 로컬 코드 설치로 취급하세요.
내장 안전장치:
허용 루트 — 호스트 경로 작업은
CITYJSON_MCP_ALLOWED_ROOTS,CITYJSON_MCP_INPUT또는 관리형 작업 공간 내에 있어야 합니다. 브라우저 업로드에는 입력 디렉터리 내부의 무작위 안전 파일 이름이 할당됩니다.임의 셸 도구 없음 —
run_shell명령이나 제한 없는run_cjioMCP 도구가 없습니다.셸 보간 없음 — 외부 프로그램은 인자 배열과
shell: false로 호출됩니다.타입이 지정된 도구 스키마 — Zod가 유형, 열거형, EPSG 정수, bbox 형태, 데이터베이스 스키마 식별자 등을 제한합니다.
PostgreSQL 비밀번호는 환경에 유지 — 데이터베이스 도구 스키마에는 비밀번호 필드가 없습니다.
DB 내보내기 SQL 가드 — 세미콜론이나 명백한 변경 키워드가 없는 단일
SELECT문자열만 허용됩니다. 그래도 필요한 권한만 가진 데이터베이스 역할을 사용하세요.명령 시간 초과/출력 상한 — 하위 프로세스는 기본적으로 120초 시간 초과와 제한된 캡처 출력을 사용합니다. 대규모 작업에는
CITYJSON_MCP_COMMAND_TIMEOUT_MS를 설정하세요.
공유 또는 프로덕션 환경에서는 실제로 필요한 파일 시스템 및 데이터베이스 권한만 가진 OS 계정/컨테이너에서 MCP를 실행하세요.
Docker
포함된 docker/Dockerfile은 다음을 설치합니다:
Node 런타임 + MCP 패키지 종속성
cjiocjdbcjvalval3ditycitygml-tools
대부분의 사용자는 게시된 이미지를 가져와야 합니다:
docker pull yarroudh/cityjson-mcp:latest로컬 소스 빌드의 경우 나머지를 빌드하기 전에 두 개의 비용이 많이 드는 컴파일러 단계를 캐시하세요:
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 .로컬 빌드 후 docker run --rm --entrypoint node cityjson-mcp /app/scripts/doctor.mjs를 실행하여 다섯 개의 실행 파일을 모두 확인하세요.
GitHub Actions에서 게시
.github/workflows/docker-publish.yml의 워크플로는 네이티브 러너에서 linux/amd64 및 linux/arm64 이미지를 빌드하고, 하나의 멀티플랫폼 매니페스트를 만들고, yarroudh/cityjson-mcp로 푸시합니다.
Settings → Secrets and variables → Actions에서 GitHub 저장소를 구성하세요:
변수
DOCKERHUB_USERNAME:yarroudh시크릿
DOCKERHUB_TOKEN: 이 저장소에 쓰기 권한이 있는 Docker Hub 액세스 토큰
Actions 탭에서 워크플로를 수동으로 실행하거나 버전 태그를 게시하세요:
git tag v0.1.0
git push origin v0.1.0버전 태그는 0.1.0, 0.1 및 latest를 게시합니다. BuildKit 캐시는 이후 실행을 위해 유지되므로 변경되지 않은 val3dity 및 cjval 레이어는 다시 컴파일할 필요가 없습니다.
개발용 PostGIS:
docker compose -f docker/docker-compose.postgis.yml up -ddocker/README.md를 참조하세요.
개발 구조
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/MCP 프로토콜 계층은 공식 Model Context Protocol TypeScript 서버 SDK의 안정적인 v2 라인과 stdio 전송을 사용합니다.
다이어그램
모든 Mermaid 소스는 diagrams/*.mmd에 저장됩니다. 체크인된 PNG 파일은 동일한 그래프 정의에서 300-DPI Graphviz 출력으로 생성되며, 문서/슬라이드에서 선명하게 유지되도록 수천 픽셀 범위의 크기를 가집니다.
다시 생성:
python3 scripts/render_diagrams.py렌더러는 이 README에서 사용하는 Mermaid 순서도 하위 집합을 지원하며 Graphviz dot 실행 파일이 필요합니다.
현재 PNG 파일:
테스트
네이티브 테스트는 외부 지리공간 백엔드가 필요하지 않습니다:
npm test다음을 테스트합니다:
CityJSON 파싱 및 요약 생성
변환/역양자화된 객체 bbox 계산
네이티브 유형/bbox/속성 쿼리
포함된 예제 JSON
모든 .mjs 소스 파일의 구문을 확인합니다:
npm run check외부 어댑터는 의도적으로 공식 CLI의 얇은 래퍼입니다. 배포 환경의 경우 배포하는 정확한 백엔드 버전에 고정된 통합 테스트를 추가하세요.
알려진 제한 사항 / v0.1 결정
네이티브
cityjson_open은 현재 일반 CityJSON JSON 파일을 메모리에 로드합니다. 매우 큰 CityJSONSeq 스트림의 경우 백엔드 워크플로우를 사용하거나 스트리밍 어댑터를 추가하세요.데이터셋 핸들은 MCP 서버 프로세스의 수명 동안만 유지됩니다. 클라이언트/서버를 재시작하면 기존
dataset_id값이 무효화됩니다. 재시작 후 소스/저장 파일을 다시 여세요.파생 작업공간 파일은 자동으로 삭제되지 않습니다. 이는 추적 가능성을 위한 의도된 동작이지만, 작업공간을 주기적으로 정리하세요.
cityjson_query는 각 CityObject에 명시적으로 저장된 지오메트리에서 bbox를 계산합니다. 모든 하위 지오메트리를 상위 bbox에 자동으로 통합하지 않습니다.cityjson_spec_read,cityjson_schema_read, 그리고 확장 레지스트리/스키마 도구는 표준 CityJSON 엔드포인트에 대한 아웃바운드 네트워크 접근이 필요합니다.cityjson_spec_outline은 번들된 인덱스에서 작동합니다.cityjson_to_citygml은 검증되지 않은 CLI 플래그에 의존하는 대신 의도적으로 대상 CityGML 버전 선택을 설치된citygml-tools기본값에 맡깁니다.val3dity는 GPL-3.0 소프트웨어입니다. 이 프로젝트는 실행 파일을 외부 백엔드로 호출하며 이를 벤더링하지 않습니다. 자체 배포/배포 모델에 대한 라이선스 영향을 검토하세요.제공된 Docker 기본 이미지에는 val3dity 또는 citygml-tools가 포함되어 있지 않습니다.
업스트림 참조
CityJSON 사양: https://www.cityjson.org/specs/
CityJSON 사양 저장소: https://github.com/cityjson/specs
CityJSON 확장 레지스트리: https://github.com/cityjson/extensions
val3dity: https://github.com/tudelft3d/val3dity
citygml-tools: https://github.com/citygml4j/citygml-tools
기존 사양 전용 CityJSON MCP: https://github.com/cityjson/cj-mcp
MCP TypeScript SDK: https://github.com/modelcontextprotocol/typescript-sdk
Cursor MCP 문서: https://cursor.com/docs/mcp
VS Code MCP 문서: https://code.visualstudio.com/docs/agents/reference/mcp-configuration
라이선스
이 저장소의 코드는 MIT 라이선스에 따라 제공됩니다. LICENSE를 참조하세요.
외부 백엔드는 각자의 라이선스에 따라 별도의 소프트웨어로 유지됩니다. 특히 val3dity는 GPL-3.0, citygml-tools는 Apache-2.0이며, cjio/cjval/cjdb는 각자의 업스트림 라이선스 파일을 보유합니다. 이 저장소의 어떤 내용도 해당 프로젝트를 재라이선스하지 않습니다.
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