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_TOKEN | No | Optional shared secret for authentication | |
| QGIS_MCP_LOG_FILE | No | Log file path (empty to disable) | ~/.local/share/qgis-mcp/server.log |
| QGIS_MCP_LOG_LEVEL | No | File log level | INFO |
| QGIS_MCP_TOOL_MODE | No | granular (102 tools) or compound (~23 grouped) | granular |
| QGIS_MCP_TRANSPORT | No | MCP transport: stdio or streamable-http | stdio |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| 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_projectC | Load a QGIS project from a .qgs/.qgz file path. |
| create_new_projectC | Create a new empty QGIS project and save it to the given path. |
| save_projectB | Save the current project. Optionally specify a new path. |
| get_layersA | 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_layerC | 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_visibilityC | Set a layer's visibility in the layer tree (show/hide on map). |
| zoom_to_layerA | 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_featuresB | 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_featuresA | Select features in a layer by expression or feature IDs. |
| get_selectionA | 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_statisticsA | 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_calculatorA | 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_layerB | 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_bookmarkA | Remove a spatial bookmark by its ID. |
| get_map_themesA | Get map themes (visibility presets). Each theme stores which layers are visible. |
| add_map_themeB | Create a map theme from the current layer visibility state. If a theme with this name exists, it will be updated. |
| remove_map_themeC | 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_commandsB | 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_layoutC | 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_infoA | 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_groupA | Create a new layer group in the layer tree. Optionally specify a parent group name. |
| move_layer_to_groupB | 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_layerB | 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_fieldC | 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_infoB | 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_legendB | 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_pictureA | 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_atlasA | 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_layoutC | Remove a print layout from the project. |
| execute_sqlB | 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
- 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/lefcgis/qgis-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server