QGIS MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| QGIS_MCP_HOST | No | Host for socket connection | localhost |
| QGIS_MCP_PORT | No | Port for socket connection | 9876 |
| QGIS_MCP_TRANSPORT | No | MCP transport: stdio or streamable-http | stdio |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| completions | {} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| pingA | Check connectivity to the QGIS plugin server. Returns pong if connected. |
| diagnoseA | Run diagnostic checks on the QGIS MCP stack. Reports QGIS version, plugin/server version match, processing providers, connected clients, and project status. |
| get_qgis_infoA | Get QGIS version, profile path, and plugin count. |
| get_project_infoA | Get current project metadata: filename, title, CRS, layer count, and summary of layers. |
| load_projectB | Load a QGIS project from a .qgs/.qgz file path. |
| create_new_projectA | Create a new empty QGIS project and save it to the given path. |
| save_projectA | Save the current project. Optionally specify a new path. |
| get_layersB | List layers in the current project with IDs, names, types, visibility, and type-specific info. Use limit/offset for pagination. Response includes total_count. |
| add_vector_layerC | Add a vector layer (shapefile, GeoJSON, GeoPackage, etc.) to the project. |
| add_raster_layerC | Add a raster layer (GeoTIFF, etc.) to the project. |
| remove_layerA | Remove a layer from the project by its layer ID. This is irreversible. |
| find_layerA | Find layers by name pattern. Supports fnmatch wildcards (e.g. 'roads*') and substring matching. |
| create_memory_layerB | Create a new in-memory vector layer. geometry_type: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon. fields: [{name, type}] where type is integer, double, string, date, datetime. |
| set_layer_visibilityA | Set a layer's visibility in the layer tree (show/hide on map). |
| zoom_to_layerB | Zoom the map canvas to the full extent of the specified layer. |
| get_layer_featuresA | Get features from a vector layer. Flat dicts: _fid + attributes at top level. expression filter (QGIS, e.g. "name = 'Berlin'", "population > 1000000"), limit (max 50, default 10), offset for paging, optional geometry in _geometry key. |
| get_field_statisticsA | Compute aggregate statistics (count, sum, mean, min, max, stdev) for a numeric field. For non-numeric fields returns count and distinct values. |
| add_featuresA | Add features to a vector layer. Each feature: {attributes: {field: value}, geometry_wkt: 'POINT(1 2)'}. Returns count of added features. |
| update_featuresA | Update feature attributes. updates: [{fid: 1, attributes: {field: value}}]. Returns count of updated features. |
| delete_featuresA | Delete features by feature IDs or expression filter. Provide either fids (list of ints) or expression (string), not both. |
| select_featuresC | Select features in a layer by expression or feature IDs. |
| get_selectionB | Get the current selection for a layer. Returns feature IDs and count. |
| clear_selectionB | Clear the selection on a layer. |
| set_layer_styleA | Set symbology. style_type: 'single' (one symbol), 'categorized' (unique values), 'graduated' (numeric ranges). field required for categorized/graduated. color_ramp: QGIS ramp name (e.g. 'Spectral', 'Viridis', 'Blues'). classes: graduated class count (default 5). |
| get_canvas_extentA | Get the current map canvas extent and CRS. |
| set_canvas_extentA | Set the map canvas extent. Coordinates should be in the specified CRS (default: project CRS). |
| get_canvas_screenshotA | Grab a fast screenshot of the current map canvas widget (no re-render). Returns the image inline. Much faster than render_map. |
| get_raster_infoA | Get raster layer info: band count, dimensions, CRS, extent, per-band statistics, nodata values. |
| execute_processingB | Execute a QGIS Processing algorithm. Use get_algorithm_help to discover parameters. Layer params accept layer IDs or file paths. Set OUTPUT to 'memory:' for temp layers. |
| list_processing_algorithmsA | Search for processing algorithms by keyword and/or provider. Returns id, name, provider for each match. |
| get_algorithm_helpA | Get detailed help for a processing algorithm: parameters (name, type, optional, default), outputs, and description. |
| create_processing_modelA | Build QGIS Processing Model (.model3) from structured spec; save to user models folder, register in Processing Toolbox. Only call needed: algorithm discovery + param validation run in the plugin against the live registry, so do NOT call list_processing_algorithms or get_algorithm_help first. Pass keyword ('buffer') or full id ('native:buffer'); handler resolves it. Ambiguous hint returns candidate list to refine and retry. Bad param/output names reported with the valid set. Spec: inputs: [{name, type, description?, default?, optional?, parent_layer? (for field/distance), options? (for enum)}]. Types: vector, feature_source, raster, field, number, integer, distance, string, boolean, extent, crs, point, file, folder, enum, multiple_layers. steps: [{id, algorithm, description?, parameters: {ALG_PARAM: value}}]. algorithm = keyword or full id. Param values: '@input_name' = model input value '$step_id.OUTPUT' = earlier step output '=expression' = QGIS expression at run time else = static literal (number/bool/string/list) outputs: [{name, from_step, from_output, description?}] = exposed outputs; omit to expose the last step OUTPUT as 'Result'. Name collision appends a suffix (name_2.model3, ...). Response returns the actual 'name', the 'requested_name', and 'resolved_steps' (which algorithm each hint mapped to). |
| list_processing_modelsA | List registered Processing models (the 'model' provider). Returns id, name, group for each. Use run_model to execute one. |
| run_modelA | Run a Processing model by registered id (e.g. 'model:myflow') or by a .model3 file path. 'parameters' maps the model's input names to values (layer ids/paths, numbers, etc.). |
| get_processing_providersA | List Processing providers (native, gdal, grass, saga, model, ...) with algorithm counts and active status. Use to diagnose missing algorithms. |
| execute_processing_batchA | Run one algorithm once per parameter dict in 'parameters_list'. Returns a per-run result with index and success/error status. Use for applying the same operation over many inputs in a single round-trip. |
| raster_calculatorA | Band math via the QGIS raster calculator. Reference loaded raster layers in the expression as 'LayerName@band' (e.g. '("dem@1" > 1000) * 1'). Writes a GeoTIFF to output_path. Output grid/extent taken from reference_layer (layer id or name), defaulting to the first loaded raster. |
| zonal_statisticsB | Per-polygon stats from a raster (native:zonalstatisticsfb). stats int codes: 0=count 1=sum 2=mean 3=median 4=stdev 5=min 6=max 7=range 8=minority 9=majority 10=variety 11=variance (default [0,1,2]). New columns prefixed by 'prefix'. No output_path = in-memory layer. |
| sample_raster_valuesA | Sample raster pixel values at points. 'points' is a list of [x, y] in the raster's CRS. Omit 'band' to sample all bands. Use transform_coordinates first if your points are in a different CRS. |
| export_layerA | Export vector/raster to disk; format from output_path extension (.gpkg, .shp, .geojson, .tif, ...). target_crs (e.g. 'EPSG:4326') reprojects on export. filter_expression (vector only) exports a subset matching a QGIS expression. |
| field_calculatorB | Add (if missing) + populate a field from a QGIS expression, per feature, in-place. field_type: string|int|double|bool|date|datetime (default double). Example: expression='$area', field_name='area_m2'. Returns updated feature count. |
| get_unique_valuesA | Return the distinct values of a field. Use 'limit' to cap results (-1 for all). Useful before building categorized symbology or filters. |
| spatial_joinA | Join attributes by location (native:joinattributesbylocation). predicates int list: 0=intersects 1=contains 2=equals 3=touches 4=overlaps 5=within 6=crosses (default [0]). method: 0=one-to-many 1=first match (default) 2=largest overlap. join_fields = copied columns (default all). No output_path = in-memory layer. |
| render_mapB | Render the current map canvas to an image. Returns the image inline so you can see it. Optionally saves to a file path on disk. |
| execute_codeA | Execute arbitrary PyQGIS code. Use for operations not covered by other tools. Has access to QgsProject, iface, and core QGIS classes. Returns stdout/stderr. |
| get_active_layerA | Get the currently active (selected) layer in the QGIS layer panel. |
| set_active_layerA | Set the active layer in the QGIS layer panel by layer ID. |
| get_canvas_scaleA | Get the current map canvas scale, rotation, and magnification factor. |
| set_canvas_scaleA | Set the map canvas scale and/or rotation. Provide scale as denominator (e.g. 50000 for 1:50000). Rotation in degrees (0-360). |
| get_layer_labelingA | Get the labeling configuration of a vector layer: enabled state, field, font size, color. |
| set_layer_labelingB | Configure labeling for a vector layer. Set enabled=false to disable labels. Set field_name to the attribute field to label with. Optional: font_size (float), color (hex like '#000000'). |
| get_layer_crsA | Get the coordinate reference system (CRS) of a layer: EPSG code, description, whether geographic, and PROJ4 string. |
| set_layer_crsA | Set the CRS of a layer (e.g. 'EPSG:4326'). This does NOT reproject data — it only changes how the layer's coordinates are interpreted. |
| get_bookmarksA | Get spatial bookmarks from the project. Each bookmark has a name, group, extent (xmin/ymin/xmax/ymax), and CRS. |
| add_bookmarkA | Add a spatial bookmark to the project for quick navigation. Provide a name and extent (xmin/ymin/xmax/ymax) with CRS. |
| remove_bookmarkB | Remove a spatial bookmark by its ID. |
| get_map_themesA | Get map themes (visibility presets). Each theme stores which layers are visible. |
| add_map_themeA | Create a map theme from the current layer visibility state. If a theme with this name exists, it will be updated. |
| remove_map_themeB | Remove a map theme by name. |
| apply_map_themeA | Apply a map theme — restores the layer visibility state saved in the theme. |
| set_project_crsA | Set the project coordinate reference system (e.g. 'EPSG:4326', 'EPSG:3857'). This changes how layers are projected on the map canvas. |
| batch_commandsA | Execute multiple commands in a single round-trip. Each command is {"type": "", "params": {...}}. Destructive commands (execute_code, remove_layer, delete_features, set_setting, reload_plugin) are not allowed in batch — use them individually. |
| list_layoutsA | List all print layouts in the current project with names and page counts. |
| export_layoutA | Export a print layout to file. format: 'pdf', 'png', 'jpg', 'svg'. dpi: resolution (default 300). |
| get_message_logA | Get QGIS message log entries. Filter by level ('info', 'warning', 'critical') and/or tag (e.g. 'QGIS MCP'). Returns newest first. |
| list_pluginsA | List installed QGIS plugins with name, enabled status, and version. Set enabled_only=true to list only active plugins. |
| get_plugin_infoB | Get detailed info for a specific plugin: name, enabled, version, description, author, path. |
| reload_pluginA | Reload a QGIS plugin by name. Cannot reload the MCP plugin itself. Useful during plugin development. |
| get_layer_treeA | Get the full layer tree structure with groups and layers. Returns recursive tree with type, name, visibility, and children. |
| create_layer_groupB | Create a new layer group in the layer tree. Optionally specify a parent group name. |
| move_layer_to_groupC | Move a layer into a layer group by group name. |
| set_layer_propertyB | Set a layer property. Supported properties: opacity (0.0-1.0), name (string), min_scale, max_scale (float), scale_visibility (bool). |
| get_layer_extentA | Get the spatial extent (bounding box) and CRS of a layer. |
| get_project_variablesA | Get all project-level variables (key-value pairs set in Project Properties). |
| set_project_variableB | Set a project-level variable. Variables are accessible in expressions as @key. |
| validate_expressionA | Validate a QGIS expression. Returns whether it's valid, any parse errors, and referenced column names. Optionally test against a layer's fields. |
| get_settingA | Read a QGIS setting by key path (e.g. 'qgis/sketching/sketching_enabled'). |
| set_settingC | Write a QGIS setting. Use with care — incorrect settings can affect QGIS behavior. |
| transform_coordinatesA | Transform coordinates between CRS. Accepts a point {x, y}, a point list [{x, y}, ...], or a bbox {xmin, ymin, xmax, ymax}. Returns the same format. |
| add_web_layerC | Add a web layer (XYZ, WMS, WFS) to the project. service: 'xyz', 'wms', 'wfs'. |
| add_table_joinC | Add a table join to a vector layer. |
| add_fieldB | Add a new field to a vector layer. field_type: 'string', 'int', 'double', 'bool', 'date', 'datetime'. |
| delete_fieldB | Delete a field from a vector layer. |
| rename_fieldC | Rename a field in a vector layer. |
| apply_style_qmlC | Apply a QGIS QML style file to a layer. |
| save_style_qmlC | Save a layer's style to a QGIS QML file. |
| create_layoutC | Create a new print layout. |
| add_layout_mapB | Add a map item to a print layout at specified position and size (in millimeters). |
| get_layout_infoA | List items in a print layout (type, id, uuid, position, size) and page count. |
| add_layout_labelB | Add a text label to a print layout (mm). text may contain [% expression %] for dynamic content. color is hex (e.g. '#000000'). |
| add_layout_legendA | Add a legend to a print layout, linked to a map item (defaults to the first map item). Position/size in mm. |
| add_layout_scalebarB | Add a scale bar to a print layout, linked to a map item. style e.g. 'Single Box', 'Double Box', 'Line Ticks Up', 'Numeric'. |
| add_layout_pictureB | Add a picture or SVG (logo, north arrow) to a print layout. path is an image or SVG file path. Position/size in mm. |
| add_layout_tableB | Add an attribute table for a vector layer to a print layout. max_rows caps the number of features shown. Position/size in mm. |
| configure_atlasB | Configure a print layout's atlas: coverage_layer (vector layer id) drives one page per feature. Optional page_name_expression, filter_expression, sort_expression. |
| export_atlasA | Export a configured atlas. format 'pdf' writes a single multi-page file at output_path; image formats ('png','jpg','tif') write one file per feature into the output_path directory. Call configure_atlas first. |
| remove_layoutB | Remove a print layout from the project. |
| execute_sqlA | SQL across loaded layers via a virtual layer; reference layers by name in FROM/JOIN. as_layer=True registers the result as a new layer (set geometry_field for spatial output); else returns rows inline (max 1000). layers limits sources by layer id. |
| evaluate_expressionA | Evaluate a standalone QGIS expression to a scalar value (e.g. aggregate('layer','sum','field'), @project_var, now()). Optional layer_id adds layer scope. Distinct from validate_expression (validate only) and field_calculator (per-feature). |
| identify_featuresA | Identify features at a point [x, y] in project CRS across layers (map-click analogue). tolerance (map units) expands the search; 0 = exact hit. layer_ids limits the search (default: visible vector layers). limit caps features per layer. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| analyze_layer | Deeply inspect a layer's schema, sample data, and compute detailed field statistics |
| spatial_analysis | Run a spatial operation between two layers with CRS validation |
| create_processing_model | Translate a natural-language workflow description into a saved QGIS Processing Model |
| style_map | Create a thematic map with categorized or graduated symbology |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| qgis_info | QGIS version, profile, and plugin count |
| project_info | Current project metadata, CRS, layer count, layer summary |
| layer_list | All layers with IDs, names, types, visibility |
| llms_context | Capabilities summary for LLM context — lists all tools, resources, and usage tips |
Latest Blog Posts
- 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/nkarasiak/qgis-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server