Skip to main content
Glama
README.md
![QGIS](https://img.shields.io/badge/QGIS-3.22-green?logo=qgis)
![Python](https://img.shields.io/badge/python-3.12-blue)
[![Build and Release](https://github.com/piatkowski/qgis-mcp/actions/workflows/release.yml/badge.svg)](https://github.com/piatkowski/qgis-mcp/actions/workflows/release.yml)
![License](https://img.shields.io/github/license/piatkowski/qgis-mcp)

# 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