GIS Assistant MCP
Provides tools for AI-powered GIS workflow automation through QGIS, translating natural-language requests into validated QGIS Processing plans, executing them step-by-step, and reporting results. Enables planning, running, resuming, and diagnosing GIS workflows using approved QGIS Processing algorithms.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@GIS Assistant MCPclip the parcels layer to the city boundary and save it to my workspace"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
gis-assistant-mcp
AI-powered GIS workflow automation via the Model Context Protocol (MCP), backed by QGIS.
Translates natural-language requests into validated QGIS Processing plans, executes them step-by-step, and reports results — through MCP tools (Claude Code / any MCP client) or the built-in chat UI inside QGIS.
Architecture
┌──────────────────┐
Claude Code ──MCP/stdio──▶ │ │
gis-assistant engine ──┤ TCP/NDJSON ──▶ QGIS Plugin
QGIS Chat UI ──HTTP────────▶ │ │
│ └──────────────────┘
├── Claude or OpenAI (plan generation)
└── Local safety validationTwo transport options share the same core engine:
MCP/stdio (
gis-assistant): For Claude Code or any MCP client. Runs as a stdio server.HTTP API (
gis-assistant-api): For the QGIS chat dock widget. Runs as a local HTTP server on port 8100 with bearer token auth.
Both transports call the same GISEngine class, which generates plans through a provider's structured-output API, validates them against an algorithm allowlist and path confinement rules, then executes each step by sending commands to the QGIS MCP plugin over a TCP socket.
Related MCP server: QGIS MCP Server
Prerequisites
QGIS 3.x with the qgis_mcp plugin by Juan Santos installed and running — this project is a separate MCP server that drives that plugin over its socket protocol; see Acknowledgments
Python 3.10+
uv package manager
ANTHROPIC_API_KEY— Claude is the default provider. (OpenAI is an optional alternative; see Choosing a provider.)
Installation
cd /path/to/gis-assistant-mcp
uv sync # Claude (default)
uv sync --extra openai # ...or add the optional OpenAI providerConfiguration
Environment Variables
Variable | Default | Description |
|
|
|
| (required for Claude) | Read by the Anthropic SDK |
| (required for OpenAI) | Read by the OpenAI SDK. Needs the |
| per provider | Overrides the provider default — |
|
| Output directory (all outputs confined here) |
|
| Port for the HTTP API server |
| (auto-generated) | Bearer token for HTTP API auth. If unset, a random token is generated at startup and printed to stdout. |
Choosing a provider
Claude (claude-opus-5) is the default and needs no extra install. To use OpenAI
instead:
uv sync --extra openai
export GIS_PLANNER_PROVIDER=openai OPENAI_API_KEY=...Both providers go through the same two-method seam in llm.py, so the engine
holds no vendor-specific code and switching changes no behaviour beyond the model.
On token usage. Adaptive thinking is enabled on both Claude call paths. Plan generation genuinely needs it — the model has to reason about CRS and units, choose among 103 allowed algorithms, and chain one step's outputs into the next — but every request then spends reasoning tokens on top of the response, and that applies to error diagnosis too, not just planning.
This server calls the Anthropic API with an ANTHROPIC_API_KEY, billed per
token. A Claude Pro or Max subscription covers Claude apps such as Claude Code and
claude.ai, but not API usage — the two are separate and metered differently.
Measured input for a typical request is ~1,900 tokens (system prompt 1,621 + a six-layer project context). With output and thinking estimated at 1.8–5.8k tokens:
Model | Cost per plan | Plans per $1 |
| $0.05 – $0.15 | 6 – 18 |
| ~$0.03 | ~32 |
| ~$0.02 | ~63 |
To spend less: set GIS_PLANNER_MODEL to a cheaper model, or drop thinking from
AnthropicProvider in src/gis_assistant/llm.py.
Running without an API key
Only plan generation needs a model. The execution engine does not, and because the planner is constructed lazily, no key is read unless you call a planning tool:
Needs a key | No key required |
|
|
So an MCP client that is already a model — Claude Code, for instance — can skip
the built-in planner entirely: call gis.list_capabilities to learn the allowed
operations and limits, author the plan JSON itself, then hand it to gis.run_plan.
Safety validation, path confinement, @-reference resolution and the confirm/resume
gate all still apply, because they live in the executor rather than the planner.
The internal planner exists for the QGIS chat dock, which has no model of its own.
The test suite needs no key and makes no network calls at all:
uv sync && uv run pytest -q # 72 passed, 6 skippedMCP Client Setup (Claude Code)
Add to your .mcp.json (e.g. in your workspace root):
{
"mcpServers": {
"gis_assistant": {
"command": "uv",
"args": ["--directory", "/path/to/gis-assistant-mcp", "run", "gis-assistant"],
"env": {
"GIS_WORKSPACE": "/path/to/your/workspace"
}
}
}
}QGIS Chat UI Setup
No MCP client needed. Start the HTTP API and use the chat dock widget inside QGIS:
Start the QGIS MCP plugin socket server (Plugins > QGIS MCP > Start Server)
Open the chat dock: Plugins > QGIS MCP > GIS Assistant Chat
Click Start Engine — this launches the HTTP API as a subprocess and auto-connects
Type your GIS request in the chat input
Alternatively, start the API manually:
cd /path/to/gis-assistant-mcp
uv run gis-assistant-api
# Prints: GIS_API_TOKEN=<token>Then paste the token into the chat dock's token field and click Connect.
Tools
Tool | Description |
| Generate a workflow plan from a natural-language prompt (no execution) |
| Resolve clarification questions from a previous |
| Plan and execute a workflow end-to-end |
| Execute a specific plan JSON (for plan → review → edit → execute workflows) |
| Resume a blocked execution after a confirmation step |
| Diagnose a GIS/QGIS error and suggest fixes |
| Show details of the last plan and execution results |
| List supported operations, algorithms, and workspace policy |
HTTP API Endpoints
When running gis-assistant-api, the following REST endpoints are available on http://127.0.0.1:8100. All endpoints (except /health) require Authorization: Bearer <token>.
Method | Path | Body | Description |
GET |
| - | Health check (no auth) |
GET |
| - | Check if QGIS socket is reachable |
POST |
|
| Generate a workflow plan |
POST |
|
| Resolve clarification questions |
POST |
|
| Plan and execute end-to-end |
POST |
|
| Execute a specific plan dict |
POST |
|
| Resume after confirmation |
POST |
|
| Diagnose an error |
GET |
| query: | List supported algorithms |
GET |
| - | Show last plan/report |
Error responses use a consistent envelope: {"status": "error", "message": "...", "details": {...}}.
Safety
No
execute_code: Arbitrary Python execution is intentionally excluded.Algorithm allowlist: Only approved
native:andgdal:processing algorithms can run (103 algorithms).Path confinement: All output paths are resolved and validated to stay within the workspace directory.
Confirmation steps: Plans include
confirmsteps before overwriting existing files, which halt execution until approved viagis.resume.Plan size limits: Maximum 20 steps per plan.
Main-thread processing: The QGIS plugin executes processing algorithms on the main thread. Large raster operations (warps, merges, hillshades on multi-GB data) will freeze the QGIS UI. Keep operations scoped to smaller datasets, or run heavy jobs directly from the QGIS Processing Toolbox.
Packaging
To create a clean distribution zip (excludes __pycache__, .venv, .git, caches):
./scripts/build_dist.shThis produces dist/gis-assistant-mcp.zip including uv.lock for reproducible installs. Without uv.lock, uv sync resolves latest allowed versions which may drift.
Development
uv sync --group dev # install test dependencies
uv run pytest tests/ -vAcknowledgments
The QGIS socket client in this project is adapted from qgis_mcp by Juan Santos, which is itself based on BlenderMCP by Siddharth Ahuja.
This is not a fork of qgis_mcp. It is a separate MCP server that drives the qgis_mcp QGIS plugin across that plugin's socket protocol — 12 of qgis_client.py's 113 substantive lines coincide with upstream, all of them send_command names fixed by the wire protocol. See NOTICE for the retained copyright notices and ARCHITECTURE.md for a capability comparison.
License
MIT License. See LICENSE; third-party copyright notices are retained in NOTICE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Ask in plain English, get a rendered, shareable map from live public data. 24 geospatial tools.
Durable, user-controlled goals and governed plans for AI agents.
Checked language for AI-written agent workflows: limits, cost and data flows known before running.
GIS tools for AI agents: 65 free tools + 8 paid (hazard/site-scouting/GeoJSON export)
Related MCP Servers
- AlicenseCqualityAmaintenanceAn MCP server that enables AI assistants to directly control QGIS for tasks like layer management, feature editing, and map rendering. It provides a suite of 50 tools to execute processing algorithms and manage GIS projects through natural language commands.125359GPL 2.0
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with QGIS, supporting project management, layer inspection, spatial queries, styling, and map export in both headless and desktop modes.-
- FlicenseNot gradedqualityDmaintenanceEnables interaction with Geo-INQUIRE OGC API Processes for geospatial operations, including planning, execution, and job management through natural language.-
- AlicenseNot gradedqualityCmaintenanceConnects AI assistants (Claude, Cursor, etc.) to QGIS 4.x via MCP, enabling natural language-driven GIS workflows through 37+ tools, including data loading, processing, and spatial analysis.GPL 2.0