QGIS MCP
by piatkowski
README.md


[](https://github.com/piatkowski/qgis-mcp/actions/workflows/release.yml)

# QGIS MCP [PL]
**[English](#english) | [Polski](#polski)**
---
<a id="english"></a>
## English
### 1. Project description
QGIS MCP is a local [MCP](https://modelcontextprotocol.io) server that lets **Claude Desktop** (others as well) inspect and transform layers in the QGIS project you currently have open — summarize a layer in one call, filter and select features by expression, reproject, clip, and merge layers, compute field statistics, add computed fields, and export to common formats — all without leaving your machine.
The system is made of two cooperating processes that never share code:
```
Claude Desktop
| stdio (MCP)
v
server/ local Python process, connects over TCP — never imports qgis.*
| 127.0.0.1:9876, newline-delimited JSON
v
plugin/qgis_mcp/ QGIS plugin, runs inside QGIS's own interpreter
v
QgsProject.instance() (the project you have open)
```
- `server/` is what Claude Desktop launches and talks MCP to.
- `plugin/qgis_mcp/` is a QGIS plugin that runs a small command server *inside* QGIS and answers requests from `server/` over a loopback-only socket (`127.0.0.1`) — nothing is ever exposed to the network.
Because everything runs locally over `127.0.0.1`, your project data never leaves your machine except for the parts of the conversation you share with Claude.
### 2. Requirements
- **QGIS** 3.22 or newer, installed and runnable on your machine.
- **Claude Desktop**, installed and signed in.
- **Python 3.12+** to run the local MCP server (a dedicated virtual environment is created for it; it does not use QGIS's bundled Python).
- macOS, Windows, or Linux — installing the plugin through QGIS's Plugin Manager (see below) works on all platforms. Some developer-only scripts in this repo (`scripts/deploy_plugin.sh`) are macOS-specific and are not needed for normal use.
### 3. Installing the QGIS Plugin
The plugin is distributed as a `.zip` file attached to the project's [GitHub Releases](https://github.com/piatkowski/qgis-mcp/releases) page (`qgis_mcp-<version>.zip`).
1. Download the latest `qgis_mcp-<version>.zip` from the Releases page.
2. In QGIS, open **Plugins → Manage and Install Plugins…**
3. Go to the **Install from ZIP** tab.
4. Select the downloaded `.zip` file and click **Install Plugin**.
5. Make sure **QGIS MCP** is checked/enabled in the plugin list.
Once enabled, the plugin **automatically starts a command server** listening on `127.0.0.1:9876` — there is nothing else to click or start. You can confirm it's running from the small toolbar icon / menu entry the plugin adds; that toggle only lets you stop the server, since it starts on its own so Claude Desktop can always reach it.
If you install a newer version of the plugin later, restart QGIS afterwards to make sure the updated code is loaded.
### 4. Downloading the server & configuring Claude Desktop
**a) Get the server code**
This project is managed with [uv](https://docs.astral.sh/uv/). With `uv` installed:
```bash
git clone https://github.com/piatkowski/qgis-mcp.git
cd qgis-mcp
uv sync
```
This creates a `.venv` and installs the exact dependency versions from `uv.lock` (`fastmcp`, `httpx`). Nothing from `qgis.*` is required here — this environment is completely separate from QGIS.
If you don't have `uv` installed, plain `pip` works too — dependencies are declared in `pyproject.toml`, no `requirements.txt` needed:
```bash
git clone https://github.com/piatkowski/qgis-mcp.git
cd qgis-mcp
python3 -m venv .venv
.venv/bin/pip install -e .
```
This installs the same packages, just without pinning to the exact locked versions in `uv.lock`.
**b) Point Claude Desktop at it**
Open Claude Desktop's config file:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`
Add (or merge) an entry under `mcpServers`, using the **absolute path** to the `.venv` you just created:
```json
{
"mcpServers": {
"qgis-mcp": {
"command": "/absolute/path/to/qgis-mcp/.venv/bin/python",
"args": ["-m", "server"]
}
}
}
```
On Windows, `command` would instead point at `...\qgis-mcp\.venv\Scripts\python.exe`.
**c) Restart Claude Desktop**
Quit and reopen Claude Desktop. With QGIS open and the plugin enabled, Claude should now be able to list and use the QGIS MCP tools.
**d) Verify the connection (optional, for troubleshooting)**
With QGIS running and the plugin enabled, you can check the two sides can talk directly from a terminal:
```bash
.venv/bin/python -c "from server.bridge import request; print(request('ping'))"
```
A successful response confirms the server can reach the plugin's command server inside QGIS.
### 5. Available tools
- **get_layer_summary** – for any layer, returns the following at once: number of features, geometry type, CRS, extent, and a list of fields with types and sample values – one call instead of five.
- **filter_layer_by_expression** – sets a QGIS filter expression on the layer (subset string) and returns the number of features remaining after the filter.
- **select_features_by_expression** – selects features that match the expression (e.g., "pop" > 1000) and returns their ID/number.
- **get_layer_extent_wkt** – returns the layer extent as a WKT/bbox, ready for use in the next step (e.g., clipping).
- **reproject_layer** – changes the layer's CRS and saves it as a new layer, with automatic validation of whether the transformation was successful.
- **clip_layer_to_extent** – clips a layer to the extent of another layer or the specified bbox – one of the most common actions, but it's not explicitly provided.
- **merge_layers** – merges multiple vector layers of the same geometry type into one, reporting field schema conflicts.
- **get_field_statistics** – returns the min/max/average/sum/unique values for a given numeric field without having to launch the processing toolbox.
- **add_field_with_values** – adds a new field and populates it with values from an expression (field calculator) in a single step.
- **export_layer** – exports a layer to a format (GeoJSON/Shapefile/GPKG/CSV) with automatic parameter selection.
### 6. Troubleshooting
- **Claude doesn't show any QGIS tools / can't connect.**
Check that the `mcpServers` entry in `claude_desktop_config.json` uses an absolute path to `.venv/bin/python` (or `.venv\Scripts\python.exe` on Windows), that the JSON is valid, and that you fully restarted Claude Desktop after editing it.
- **Tool calls fail with a connection/timeout error.**
Make sure QGIS is running and the QGIS MCP plugin is enabled (check **Plugins → Manage and Install Plugins**). The plugin must be running *inside* QGIS for the server to reach it — the server only relays requests, it does not run QGIS itself.
- **Error message starts with `[BridgeTimeout]` or `[BridgeError]`.**
These indicate the server couldn't reach the plugin's socket at `127.0.0.1:9876` in time — QGIS may be closed, busy, or the plugin may not be enabled. Errors prefixed with a different type (e.g. `[LayerNotFound]`, `[UnsupportedLayerType]`) come from the plugin itself and describe why the requested operation failed, not a connection problem.
- **You just installed/updated the plugin and nothing changed.**
QGIS does not hot-reload plugin code. Restart QGIS after installing a new version.
- **Port 9876 already in use / need a different port.**
Both sides read `QGIS_MCP_HOST` / `QGIS_MCP_PORT` environment variables independently. Set both consistently — for the server, in the `env` section of its `mcpServers` config entry; for the plugin, in the environment QGIS itself is launched with.
- **The plugin refuses to bind to a non-`127.0.0.1` address.**
This is intentional: the command server only ever listens on loopback, by design, so nothing on your QGIS project is ever reachable from the network.
---
<a id="polski"></a>
## Polski
### 1. Opis projektu
QGIS MCP to lokalny serwer [MCP](https://modelcontextprotocol.io), który pozwala **Claude Desktop** (i nie tylko) analizować i przekształcać warstwy w aktualnie otwartym projekcie QGIS — podsumować warstwę jednym wywołaniem, filtrować i zaznaczać obiekty wyrażeniem, przeprojektowywać, przycinać i łączyć warstwy, liczyć statystyki pól, dodawać pola obliczeniowe oraz eksportować do popularnych formatów — wszystko lokalnie, bez opuszczania Twojego komputera.
System składa się z dwóch współpracujących procesów, które nigdy nie dzielą kodu:
```
Claude Desktop
| stdio (MCP)
v
server/ lokalny proces Pythona, łączy się przez TCP — nigdy nie importuje qgis.*
| 127.0.0.1:9876, dane JSON oddzielone znakiem nowej linii
v
plugin/qgis_mcp/ wtyczka QGIS, działa wewnątrz interpretera samego QGIS
v
QgsProject.instance() (otwarty projekt)
```
- `server/` to proces uruchamiany przez Claude Desktop, komunikujący się z nim przez MCP.
- `plugin/qgis_mcp/` to wtyczka QGIS, która uruchamia niewielki serwer poleceń *wewnątrz* QGIS i odpowiada na żądania z `server/` przez gniazdo dostępne wyłącznie lokalnie (`127.0.0.1`) — nic nie jest udostępniane w sieci.
Ponieważ wszystko działa lokalnie na `127.0.0.1`, dane Twojego projektu nie opuszczają komputera, poza fragmentami rozmowy, którymi sam(a) zdecydujesz się podzielić z Claude.
### 2. Wymagania
- **QGIS** w wersji 3.22 lub nowszej, zainstalowany i uruchamialny na Twoim komputerze.
- **Claude Desktop**, zainstalowany i zalogowany.
- **Python 3.12+** do uruchomienia lokalnego serwera MCP (tworzone jest dla niego dedykowane środowisko wirtualne; nie korzysta z Pythona dołączonego do QGIS).
- macOS, Windows lub Linux — instalacja wtyczki przez menedżer wtyczek QGIS (patrz niżej) działa na wszystkich platformach. Niektóre skrypty deweloperskie w tym repozytorium (`scripts/deploy_plugin.sh`) są przeznaczone wyłącznie dla macOS i nie są potrzebne do normalnego użytkowania.
### 3. Instalacja wtyczki QGIS
Wtyczka jest dystrybuowana jako plik `.zip` dołączony do strony [GitHub Releases](https://github.com/piatkowski/qgis-mcp/releases) projektu (`qgis_mcp-<wersja>.zip`).
1. Pobierz najnowszy plik `qgis_mcp-<wersja>.zip` ze strony Releases.
2. W QGIS otwórz **Wtyczki → Zarządzaj i instaluj wtyczki…**
3. Przejdź do zakładki **Zainstaluj z ZIP**.
4. Wybierz pobrany plik `.zip` i kliknij **Zainstaluj wtyczkę**.
5. Upewnij się, że wtyczka **QGIS MCP** jest zaznaczona/włączona na liście wtyczek.
Po włączeniu wtyczka **automatycznie uruchamia serwer poleceń** nasłuchujący na `127.0.0.1:9876` — nie trzeba nic dodatkowo klikać ani uruchamiać. Działanie serwera można potwierdzić z poziomu małej ikony na pasku narzędzi / wpisu w menu dodawanego przez wtyczkę; ten przełącznik pozwala jedynie celowo zatrzymać serwer, ponieważ uruchamia się on sam, tak by Claude Desktop zawsze mógł się z nim połączyć.
Jeśli w przyszłości zainstalujesz nowszą wersję wtyczki, zrestartuj potem QGIS, aby mieć pewność, że wczytany zostanie zaktualizowany kod.
### 4. Pobranie serwera i konfiguracja w Claude Desktop
**a) Pobierz kod serwera**
Ten projekt jest zarządzany za pomocą [uv](https://docs.astral.sh/uv/). Mając zainstalowane `uv`:
```bash
git clone https://github.com/piatkowski/qgis-mcp.git
cd qgis-mcp
uv sync
```
To polecenie tworzy `.venv` i instaluje dokładnie te wersje zależności, które są zapisane w `uv.lock` (`fastmcp`, `httpx`). Nie jest tu potrzebne nic z `qgis.*` — to środowisko jest całkowicie odseparowane od QGIS.
Jeśli nie masz zainstalowanego `uv`, zwykły `pip` też zadziała — zależności są zadeklarowane w `pyproject.toml`, plik `requirements.txt` nie jest potrzebny:
```bash
git clone https://github.com/piatkowski/qgis-mcp.git
cd qgis-mcp
python3 -m venv .venv
.venv/bin/pip install -e .
```
Zainstaluje to te same pakiety, tylko bez przypięcia do dokładnych, zablokowanych wersji z `uv.lock`.
**b) Wskaż serwer w Claude Desktop**
Otwórz plik konfiguracyjny Claude Desktop:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`
Dodaj (lub połącz z istniejącą zawartością) wpis w sekcji `mcpServers`, używając **bezwzględnej ścieżki** do utworzonego przed chwilą `.venv`:
```json
{
"mcpServers": {
"qgis-mcp": {
"command": "/absolute/path/to/qgis-mcp/.venv/bin/python",
"args": ["-m", "server"]
}
}
}
```
W systemie Windows `command` powinno wskazywać zamiast tego na `...\qgis-mcp\.venv\Scripts\python.exe`.
**c) Zrestartuj Claude Desktop**
Zamknij i uruchom ponownie Claude Desktop. Przy otwartym QGIS i włączonej wtyczce Claude powinien teraz widzieć i móc używać narzędzi QGIS MCP.
**d) Sprawdzenie połączenia (opcjonalnie, do diagnostyki)**
Przy uruchomionym QGIS i włączonej wtyczce można bezpośrednio sprawdzić z terminala, czy obie strony się komunikują:
```bash
.venv/bin/python -c "from server.bridge import request; print(request('ping'))"
```
Poprawna odpowiedź potwierdza, że serwer może dotrzeć do serwera poleceń wtyczki działającego wewnątrz QGIS.
### 5. Lista narzędzi
- **get_layer_summary** – dla dowolnej warstwy zwraca od razu: liczbę obiektów, typ geometrii, CRS, zasięg, listę pól z typami i przykładowymi wartościami – jedno wywołanie zamiast pięciu.
- **filter_layer_by_expression** – ustawia filtr QGIS expression na warstwie (subset string) i zwraca ile obiektów zostało po filtrze.
- **select_features_by_expression** – zaznacza obiekty spełniające wyrażenie (np. "pop" > 1000) i zwraca ich ID/liczbę.
- **get_layer_extent_wkt** – zwraca zasięg warstwy jako WKT/bbox gotowe do użycia w kolejnym kroku (np. przycinaniu).
- **reproject_layer** – zmienia CRS warstwy i zapisuje jako nową, z automatyczną walidacją czy transformacja się udała.
- **clip_layer_to_extent** – przycina warstwę do zasięgu innej warstwy lub podanego bbox – jedna z najczęstszych czynności, a nie ma jej wprost.
- **merge_layers** – łączy kilka warstw wektorowych tego samego typu geometrii w jedną, z raportem konfliktów schematu pól.
- **get_field_statistics** – dla wskazanego pola liczbowego zwraca min/max/średnią/sumę/unikalne wartości bez konieczności odpalania processing toolboxa.
- **add_field_with_values** – dodaje nowe pole i wypełnia je wartościami z wyrażenia (field calculator) w jednym kroku.
- **export_layer** – eksportuje warstwę do formatu (GeoJSON/Shapefile/GPKG/CSV) z automatycznym doborem parametrów.
---
### 6. Rozwiązywanie problemów
- **Claude nie pokazuje żadnych narzędzi QGIS / nie może się połączyć.**
Sprawdź, czy wpis `mcpServers` w `claude_desktop_config.json` używa bezwzględnej ścieżki do `.venv/bin/python` (lub `.venv\Scripts\python.exe` w Windows), czy JSON jest poprawny, oraz czy Claude Desktop został w pełni zrestartowany po edycji pliku.
- **Wywołania narzędzi kończą się błędem połączenia/przekroczenia czasu.**
Upewnij się, że QGIS jest uruchomiony, a wtyczka QGIS MCP jest włączona (**Wtyczki → Zarządzaj i instaluj wtyczki**). Wtyczka musi działać *wewnątrz* QGIS, aby serwer mógł się z nią połączyć — sam serwer jedynie przekazuje żądania, nie uruchamia QGIS.
- **Komunikat błędu zaczyna się od `[BridgeTimeout]` lub `[BridgeError]`.**
Oznacza to, że serwer nie zdążył połączyć się z gniazdem wtyczki na `127.0.0.1:9876` — QGIS może być zamknięty, zajęty, albo wtyczka może być wyłączona. Błędy z innym prefiksem (np. `[LayerNotFound]`, `[UnsupportedLayerType]`) pochodzą z samej wtyczki i opisują, dlaczego żądana operacja się nie powiodła — to nie jest problem z połączeniem.
- **Właśnie zainstalowano/zaktualizowano wtyczkę i nic się nie zmieniło.**
QGIS nie wczytuje kodu wtyczek na gorąco. Po instalacji nowej wersji zrestartuj QGIS.
- **Port 9876 jest zajęty / potrzebny inny port.**
Obie strony niezależnie odczytują zmienne środowiskowe `QGIS_MCP_HOST` / `QGIS_MCP_PORT`. Ustaw je spójnie po obu stronach — dla serwera w sekcji `env` jego wpisu w `mcpServers`, dla wtyczki w środowisku, w którym uruchamiany jest sam QGIS.
- **Wtyczka odmawia nasłuchiwania na adresie innym niż `127.0.0.1`.**
To celowe zachowanie: serwer poleceń zawsze nasłuchuje wyłącznie lokalnie, dzięki czemu nic w Twoim projekcie QGIS nigdy nie jest dostępne z sieci.
TDQS
A3.9/5.0
Scored across 10 tools
Disambiguation5/5
Each tool has a clearly distinct purpose: summary, filtering, selection, extent retrieval, reprojection, clipping, merging, statistics, field addition, and export. No two tools overlap in functionality.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern in snake_case, e.g., get_layer_summary, filter_layer_by_expression, reproject_layer. No mixing of conventions.
Tool Count5/5
10 tools is well-scoped for a GIS MCP server covering common operations: information, filtering, selection, manipulation, and export. Not too few or too many.
Completeness3/5
Covers core data manipulation but lacks a tool to list available layers, which is a notable gap. Missing delete field/update field operations, but add and export are present.
Maintenance
ActivitySlowing
ResponsivenessNo issues