Skip to main content
Glama

QGIS MCP Server

Plugin do QGIS Desktop que sobe um servidor MCP dentro da sessão do QGIS em execução, expondo o projeto aberto do usuário a clientes MCP.

Não é um servidor standalone e não roda headless: as tools operam sobre o projeto que está na tela, no estado em que ele se encontra. Uma camada criada por geoprocessamento aparece no painel do usuário na hora.

Requisitos

  • QGIS Desktop 3.28 ou superior (Windows)

  • fastmcp e uvicorn instalados no Python embutido do QGIS

O PyQGIS não é instalável via pip — ele vem acoplado ao build do QGIS. Por isso as dependências vão para o Python do QGIS, não para o Python do sistema.

Related MCP server: mcreator-mcp

Instalação

1. Dependências no Python do QGIS

Abra o OSGeo4W Shell (vem com o QGIS, procure no menu Iniciar) e rode:

python -m pip install fastmcp uvicorn

Se der erro de permissão, abra o shell como administrador. Para confirmar que foi para o lugar certo:

python -c "import fastmcp, uvicorn; print(fastmcp.__version__)"

2. Copiar o plugin

O destino é a pasta de plugins do perfil do QGIS:

%APPDATA%\QGIS\QGIS3\profiles\default\python\plugins

Ela só existe depois que o QGIS foi aberto pelo menos uma vez. Se você usa um perfil diferente do padrão, troque default pelo nome dele — a lista está em Configurações → Perfis do usuário.

No PowerShell, a partir da raiz do repositório:

$dest = "$env:APPDATA\QGIS\QGIS3\profiles\default\python\plugins\qgis_mcp"
robocopy .\src\qgis_mcp $dest /MIR /XD __pycache__ /XF *.pyc

O /MIR espelha a pasta: arquivos apagados do repositório somem do destino também. Sem isso, um módulo antigo continuaria sendo importado pelo QGIS. O robocopy termina com código de saída 1 quando copiou algo — é sucesso, não erro.

Se preferir o Explorador de Arquivos: aperte Win+R, cole %APPDATA%\QGIS\QGIS3\profiles\default\python\plugins e copie para lá a pasta src\qgis_mcp do repositório. O nome da pasta no destino precisa continuar sendo qgis_mcp — é ele que o QGIS importa.

3. Ativar no QGIS

Complementos → Gerenciar e Instalar Complementos → Instalados e marque QGIS MCP Server.

4. Iniciar o servidor

Complementos → MCP Server → Iniciar servidor MCP. Uma mensagem confirma o endereço; o padrão é http://127.0.0.1:9876/mcp.

O log fica em Visualizar → Painéis → Mensagens do log, aba QGIS MCP.

Conectar o cliente

O transporte é HTTP, não stdio: o QGIS já está rodando, não há processo para o cliente lançar. O cliente fica na mesma máquina do QGIS e aponta para a loopback.

No PowerShell, para o Claude Code:

claude mcp add --transport http qgis http://127.0.0.1:9876/mcp

Em clientes que se configuram por arquivo JSON, a entrada equivalente é:

{
  "mcpServers": {
    "qgis": { "type": "http", "url": "http://127.0.0.1:9876/mcp" }
  }
}

Os nomes dos campos variam por cliente: o Antigravity, por exemplo, usa serverUrl e não aceita url — veja Conectar o Antigravity, abaixo.

Para conectar de outra máquina da rede local, o servidor precisa ouvir em todas as interfaces, não só na loopback. Defina a variável e reabra o QGIS — setx só vale para processos abertos depois dela:

setx QGIS_MCP_HOST 0.0.0.0

O Firewall do Windows vai pedir liberação da porta na primeira conexão. Só faça isso em rede confiável: as tools dão acesso de leitura e escrita ao projeto, sem autenticação. As variáveis disponíveis estão em .env.example.

Conectar o Antigravity

O Antigravity roda na sua máquina, então alcança a loopback direto: não há túnel, HTTPS nem domínio público no caminho. A URL é a mesma que o plugin mostra ao iniciar, http://127.0.0.1:9876/mcp.

A ordem importa. O QGIS precisa estar aberto e com o servidor iniciado antes de o Antigravity tentar conectar. Se você subir o servidor depois, não reinicie o editor: use o botão de recarregar da própria tela de MCP.

1. Abrir a configuração de MCP

No painel do agente, clique em no topo → MCP ServersManage MCP Servers. Esse botão abre o mcp_config.json do perfil para edição — prefira esse caminho a procurar o arquivo no disco, porque o local varia entre versões do editor.

Se preferir editar à mão, o global fica em:

C:\Users\<seu-usuário>\.gemini\config\mcp_config.json

Em algumas versões o arquivo do perfil está em .gemini\antigravity\mcp_config.json. Para valer só num projeto, use .agents\mcp_config.json na raiz do workspace.

2. Declarar o servidor

{
  "mcpServers": {
    "qgis": {
      "serverUrl": "http://127.0.0.1:9876/mcp"
    }
  }
}

O campo é serverUrl. O Antigravity não aceita url nem httpUrl para conexões HTTP — com o nome errado o servidor não aparece na lista, e não há mensagem dizendo por quê. Se o arquivo já tiver outros servidores, acrescente a chave "qgis" dentro do mcpServers existente em vez de substituir o bloco.

Não é preciso headers nem credenciais: o plugin não autentica ninguém.

3. Recarregar e conferir

De volta à tela MCP Servers, clique no botão de recarregar. O servidor qgis deve aparecer com as tools listadas. Do lado do QGIS, a aba QGIS MCP do painel de log (Visualizar → Painéis → Mensagens do log) registra a conexão.

Teste com um pedido que só o seu projeto sabe responder — "liste as camadas do projeto aberto no QGIS", ou "quantas feições tem a camada X". Se a resposta trouxer o que está na sua tela, a ligação está de pé.

Conferir o servidor antes de culpar o cliente

Se nada aparece, confirme primeiro que o plugin está ouvindo. No PowerShell:

Test-NetConnection -ComputerName 127.0.0.1 -Port 9876

TcpTestSucceeded : True quer dizer que o servidor está no ar e o problema é de configuração do cliente.

Abrir http://127.0.0.1:9876/mcp no navegador não é um teste válido: o endereço responde 400 Bad Request: Missing session ID. Isso é sinal de vida, e não erro de instalação — o transporte MCP exige POST com sessão, coisa que o navegador não faz.

Sobre a exposição

Ouvindo em 127.0.0.1, o servidor não está visível para a rede: só processos da própria máquina o alcançam. Entre eles não há distinção — não há autenticação, então qualquer programa local que conheça a porta tem o mesmo acesso ao projeto que o Antigravity. É o modelo dos servidores MCP locais em geral, e é bem mais contido que o túnel público exigido pelo Spark.

Conectar o Gemini Spark

O Gemini do Google aceita servidores MCP de terceiros através do Spark. Na web: gemini.google.com → Configurações e ajuda → Apps conectados → Apps personalizados para o Spark → Adicionar um app personalizado, e informe a URL do servidor MCP. No app móvel o caminho é o mesmo, pelo menu.

Requisitos do lado do Google, hoje: ter acesso ao Spark, usar uma conta pessoal (contas de trabalho ou escola não funcionam), ter 18 anos ou mais, estar nos EUA, com a interface em inglês e o Keep Activity ligado.

Há uma diferença de fundo em relação aos clientes de desktop: o Spark roda na nuvem do Google, não na sua máquina. http://127.0.0.1:9876/mcp é inalcançável para ele — a URL precisa ser pública e em HTTPS. O passo do ngrok abaixo, que para qualquer outro cliente é opcional, aqui é o único caminho.

Expor o servidor por HTTPS com o ngrok

O agente do ngrok roda na mesma máquina do QGIS e aponta para a loopback. Assim o plugin continua ouvindo só em 127.0.0.1 — não é preciso mexer em QGIS_MCP_HOST, e nada na sua rede local passa a enxergar o servidor: só o túnel.

  1. Instale e autentique o agente (o token sai do painel do ngrok):

    winget install ngrok.ngrok
    ngrok config add-authtoken SEU_TOKEN
  2. Com o servidor MCP já iniciado no QGIS, abra o túnel:

    ngrok http 9876 --host-header=rewrite

    O --host-header=rewrite faz o ngrok reescrever o cabeçalho Host para 127.0.0.1:9876. Sem isso, alguns servidores HTTP recusam a requisição por proteção contra DNS rebinding.

  3. Copie a URL Forwarding que o ngrok mostra e acrescente /mcp:

    https://xxxx-xxx-xxx-xxx-xxx.ngrok-free.app/mcp
  4. Cole essa URL no campo de app personalizado do Spark. Se o servidor não suportar Dynamic Client Registration — é o caso deste plugin, que não tem camada de autenticação —, o Spark oferece um bloco Advanced features para credenciais; deixe-o vazio.

  5. Teste pedindo ao Gemini algo simples, como listar as camadas do projeto aberto. A aba QGIS MCP do painel de log mostra a chamada chegando.

No plano gratuito a URL muda a cada reinício do ngrok, e o app precisa ser recadastrado no Spark. Um domínio reservado (plano pago) resolve isso.

Antes de abrir o túnel

Uma URL pública do ngrok apontando para este servidor dá a qualquer pessoa que souber o endereço o mesmo poder que as tools dão ao modelo: ler o projeto, rodar geoprocessamento, sobrescrever arquivos, exportar dados. O plugin não autentica ninguém.

Mitigações, em ordem de eficácia:

  • Suba o túnel só enquanto estiver usando e encerre com Ctrl+C depois.

  • Proteja com autenticação básica: ngrok http 9876 --basic-auth "usuario:senha" (a senha precisa de 8 caracteres ou mais) e informe as credenciais no bloco Advanced features do Spark. Se o Spark recusar as credenciais, volte à primeira mitigação.

  • Trabalhe num projeto de teste, não no projeto de produção, enquanto avalia.

As tools

35 tools em quatro módulos. Todas retornam {"success": bool, ...}; em caso de erro, a mensagem carrega o contexto necessário para corrigir a chamada — campos disponíveis, camadas existentes, mensagem do parser de expressões.

Inspeção — somente leitura

Tool

Para quê

get_project_info

panorama do projeto aberto

list_layers

camadas com IDs e metadados

describe_layer

CRS, extensão, provedor, geometria

get_layer_fields

esquema de atributos

count_features

contagem, com filtro opcional

get_unique_values

valores distintos de um campo

get_field_statistics

min, max, média, mediana, desvio

get_features

leitura de feições

get_layer_extent

bounding box, com reprojeção

Geoprocessamento

O QGIS tem mais de mil algoritmos; não há uma tool por operação. As três primeiras expõem o registro inteiro:

Tool

Para quê

list_algorithms

procura algoritmos por palavra-chave

describe_algorithm

esquema exato de parâmetros

validate_algorithm_parameters

checagem sem executar

run_algorithm

executa, em segundo plano

add_layer_from_source

carrega arquivo como camada

remove_layer

descarta camada da sessão

Projeto e exportação

Tool

Para quê

open_project / save_project / close_project

ciclo de vida do .qgz

set_layer_visibility / rename_layer / move_layer

árvore de camadas

export_layer

grava vetorial em arquivo

export_map_image

renderiza o mapa em PNG

list_layouts / export_layout

layouts de impressão em PDF/PNG/SVG

Operações destrutivas exigem autorização explícita (discard_unsaved, overwrite), que começa desligada.

Simbologia

Tool

Para quê

list_color_ramps

rampas de cor disponíveis

get_layer_style

como a camada está pintada

set_single_symbol

símbolo único

set_categorized_style

uma cor por valor de atributo

set_graduated_style

mapa coroplético por faixas

set_raster_style

pseudocor em banda de raster

set_layer_labels

rótulos

set_layer_opacity

transparência

load_style_file / save_style_file

estilos .qml

Arquitetura

O QGIS é uma aplicação Qt de thread única. O servidor HTTP roda numa thread de fundo para não congelar a interface, mas tocar em QgsProject, camadas ou iface a partir dela causa segfault.

Todo acesso ao QGIS passa por core.call_qgis(fn), que enfileira fn na thread principal por sinal com conexão QueuedConnection e aguarda o resultado de forma assíncrona. Nenhuma tool chama a API do QGIS diretamente.

Geoprocessamento vai além disso: run_algorithm usa QgsProcessingAlgRunnerTask para rodar em segundo plano, mantendo a interface responsiva. Algoritmos com a flag NoThreading — vários do GDAL — caem automaticamente no caminho síncrono.

Desenvolvimento

Os testes rodam sem o QGIS instalado, contra um QGIS simulado em tests/qgis_stub/:

py -m venv .venv
.venv\Scripts\Activate.ps1
pip install -e ".[dev]"
pytest

Use um Python comum aqui, não o do QGIS: a suíte roda contra o stub e não deve sujar o ambiente do QGIS. Para reinstalar o plugin depois de uma alteração, repita o robocopy do passo 2 e recarregue com o Plugin Reloader. (scripts/deploy.sh faz o mesmo a partir do WSL, se você desenvolve de lá.)

Isso valida a lógica pura — serialização, validação, truncamento, proteções e o formato das mensagens de erro. Não valida as chamadas ao PyQGIS real: assinaturas divergentes e diferenças entre builds Qt5 e Qt6 só aparecem no QGIS de verdade.

Problemas comuns

O plugin não aparece na lista. A pasta copiada precisa se chamar qgis_mcp e conter metadata.txt e __init__.py. Confira em Complementos → Gerenciar → Inválidos, que mostra o erro de carregamento.

"Dependência ausente" ao iniciar. O fastmcp foi instalado no Python errado. Refaça o passo 1 usando o OSGeo4W Shell, não o PowerShell nem o Prompt de Comando comum.

"Não foi possível ouvir na porta". Outra sessão do QGIS já está usando a porta. Feche-a, ou rode setx QGIS_MCP_PORT 9877 e reabra o QGIS.

Alterei o código e nada mudou. O Python do QGIS mantém os módulos em cache. Rode o robocopy do passo 2 de novo e recarregue com o plugin Plugin Reloader, ou reinicie o QGIS.

A interface congela. Alguma tool está bloqueando a thread principal por mais tempo que o esperado. O timeout padrão é de 30s para leituras e 600s para geoprocessamento; o log da aba QGIS MCP mostra o que estava rodando.

O Antigravity não lista as tools do qgis. Na ordem: o servidor foi iniciado no menu do QGIS (a aba QGIS MCP do log mostra o endereço); o campo no mcp_config.json é serverUrl, não url; a URL termina em /mcp; e você clicou no botão de recarregar da tela MCP Servers depois de salvar. Um servidor declarado enquanto o QGIS estava fechado continua marcado como falho até esse recarregar.

O Spark não conecta na URL do ngrok. Confirme os três pontos, nessa ordem: o servidor responde em http://127.0.0.1:9876/mcp na própria máquina; o painel do ngrok em http://127.0.0.1:4040 mostra a requisição chegando; e a URL cadastrada termina em /mcp. Se a requisição chega e volta 4xx, é o cabeçalho Host — verifique se o túnel subiu com --host-header=rewrite.

Funcionava e parou depois de reiniciar o ngrok. No plano gratuito o subdomínio é sorteado a cada execução. Remova o app personalizado no Spark e cadastre-o de novo com a URL nova.

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    A
    maintenance
    An 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.
    118
    310
    GPL 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables MCP clients to inspect and operate MCreator workspaces through MCreator's Java APIs, supporting elements, generators, resources, and builds.
    -
  • A
    license
    C
    quality
    C
    maintenance
    Enables MCP clients to inspect, validate, test, export, and query Godot projects, including live state from an open editor via a bridge addon.
    20
    70 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables MCP-capable assistants to control an open ArcGIS Pro project locally over TCP 127.0.0.1, with 68 commands and 167 tools for layers, editing, symbology, layouts, geoprocessing, and arcpy execution.
    1
    MIT