mcp-geo-server

mcp-geo-server

Enables natural language interaction with a GeoServer instance for managing workspaces, datastores, feature types, layers, styles, and OGC services (WMS/WFS) via an LLM-powered agent.

Category
访问服务器

README

mcp-geo-server

An intelligent MCP (Model Context Protocol) server that lets you drive a GeoServer instance in natural language. It is built with the Microsoft Agent Framework: an LLM-backed agent is given the GeoServer operations as tools and exposed as a single MCP tool via agent.as_mcp_server(). The LLM backend is pluggable — local Ollama, Ollama Cloud, or Anthropic Claude. Any MCP client sends a request like "how many features in topp:states?" and the agent decides which GeoServer operations to call.

Under the hood the agent can: manage workspaces, PostGIS datastores, feature types, layers and SLD styles via the REST API, and query/edit data via the OGC services (WMS, WFS GetFeature → GeoJSON, WFS-T insert/update/delete). It ships with a small Leaflet web UI and a Docker stack (GeoServer + PostGIS + Ollama) for local development.

The same async core (GeoServerClient + the geo_* tool functions) is shared by the agent and the web UI — there is exactly one place that talks to GeoServer.


Prerequisites

  • Python 3.11+
  • Docker + Docker Compose (for the local GeoServer/PostGIS stack)

1. Start the stack (Docker)

make build          # build the app image + pull GeoServer/PostGIS/Ollama
make ollama-pull    # download the LLM model into the Ollama container (once)
make docker-up      # start everything

The Compose project is named mcp-geo-server; containers are named coherently:

Service Container Endpoint
mcp mcp-geo-server-mcp http://localhost:9000/mcp — intelligent MCP server (streamable-HTTP)
webui mcp-geo-server-webui http://localhost:8000 — Leaflet test UI
geoserver mcp-geo-server-geoserver http://localhost:8080/geoserver (admin / geoserver)
ollama mcp-geo-server-ollama http://localhost:11434 — local LLM backend
postgis mcp-geo-server-postgis localhost:5432 (gis / gis / gis)

GeoServer runs with CORS_ENABLED=true so the browser UI can call OGC services directly. PostGIS has a healthcheck and GeoServer waits for it. The mcp agent talks to GeoServer and Ollama over the internal Compose network.

2. Install

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,webui]"
cp .env.example .env   # then edit as needed

3. Configuration (environment variables)

Variable Default Meaning
GEOSERVER_URL — (required) Base URL, e.g. http://localhost:8080/geoserver
GEOSERVER_USER — (required) REST username
GEOSERVER_PASSWORD — (required) REST password
GEOSERVER_DEFAULT_WORKSPACE (none) Workspace used when a tool omits one
GEOSERVER_DEFAULT_SRS EPSG:4326 SRS used when publishing without one
GEOSERVER_TIMEOUT 30 HTTP timeout (seconds)
GEOSERVER_RETRIES 2 Retry attempts on connect/timeout/502/503/504
GEOSERVER_RETRY_BACKOFF 0.5 Linear backoff factor (seconds × attempt)
GEOSERVER_VERIFY_TLS true Verify TLS certificates
GEO_MAP_OUTPUT_DIR ./maps Where generated maps / downloaded PNGs are saved
WEBUI_PORT 8000 Port for the test UI
GEO_LLM_PROVIDER ollama Agent LLM backend: ollama, ollama-cloud or anthropic
OLLAMA_HOST http://localhost:11434 Local Ollama endpoint (ollama provider)
OLLAMA_MODEL qwen2.5 Ollama model (must support tool calling); cloud model id for ollama-cloud
OLLAMA_CLOUD_HOST https://ollama.com Ollama Cloud endpoint (ollama-cloud provider)
OLLAMA_API_KEY (none) Ollama Cloud API key (required for ollama-cloud)
ANTHROPIC_API_KEY (none) Anthropic API key (required for anthropic)
ANTHROPIC_MODEL claude-sonnet-4-6 Claude model (anthropic provider)
GEO_MCP_TRANSPORT stdio MCP transport: stdio or http
GEO_MCP_HOST 0.0.0.0 Bind host when transport is http
GEO_MCP_PORT 9000 Port when transport is http

Secrets are never hardcoded — everything is read from the environment.

4. The intelligent MCP server (Microsoft Agent Framework)

The MCP server is an agent, not a flat list of tools. server.py builds a GeoServer agent (agent.py: a chat client + the geo_* functions as tools) and exposes it with agent.as_mcp_server(). The MCP client therefore sees one tool, geoserver-agent, that takes a natural-language task.

Choosing the LLM backend (GEO_LLM_PROVIDER)

Provider Value Needs Notes
Local Ollama ollama the ollama container Default. No API key; run make ollama-pull.
Ollama Cloud ollama-cloud OLLAMA_API_KEY Hosted models at https://ollama.com; set OLLAMA_MODEL to a cloud model (e.g. gpt-oss:120b).
Anthropic Claude anthropic ANTHROPIC_API_KEY Uses ANTHROPIC_MODEL (default claude-sonnet-4-6).

Examples:

# Ollama Cloud
GEO_LLM_PROVIDER=ollama-cloud OLLAMA_API_KEY=sk-... OLLAMA_MODEL=gpt-oss:120b mcp-geo-server

# Anthropic Claude
GEO_LLM_PROVIDER=anthropic ANTHROPIC_API_KEY=sk-ant-... mcp-geo-server

For Docker, set the same variables in your shell (or .env) before make docker-up; the mcp service forwards them. With ollama-cloud/anthropic the local ollama container is not needed.

Run it over either transport (selected by GEO_MCP_TRANSPORT):

# stdio (for MCP clients that spawn the process, e.g. Claude Desktop)
mcp-geo-server

# streamable-HTTP (long-lived, visible container) at http://localhost:9000/mcp
GEO_MCP_TRANSPORT=http mcp-geo-server

In Docker the mcp service runs it over HTTP. Example MCP client call:

from mcp.client.streamable_http import streamablehttp_client
from mcp import ClientSession

async with streamablehttp_client("http://localhost:9000/mcp") as (r, w, _):
    async with ClientSession(r, w) as s:
        await s.initialize()
        res = await s.call_tool("geoserver-agent",
                                {"task": "How many features are in topp:states?"})
        print(res.content[0].text)

For a stdio MCP client (claude_desktop_config.json), point command at mcp-geo-server and set the GEOSERVER_* / OLLAMA_* env vars.

5. Run the test UI

uvicorn webui.app:app --reload --port 8000

Open http://localhost:8000. The sidebar has a form for each operation (create workspace / PostGIS datastore, publish a feature type, create + assign a style, run a WFS query) plus a connection-status indicator. The map uses an OpenStreetMap basemap and shows selected layers as WMS overlays; the "Carica come GeoJSON" button fetches features via WFS and draws them with popups.

6. Tests

pytest                                  # unit + behavioural (no GeoServer needed)
GEO_RUN_INTEGRATION=1 pytest tests/integration   # live round-trip vs real GeoServer
  • tests/test_formatting.py, test_styles_helpers.py, test_ogc_helpers.py, test_map_template.py — pure helpers / template rendering.
  • tests/test_tools_behaviour.py — every tool driven with a FakeClient, asserting on the request bodies / params / WFS-T XML (no network).
  • tests/integration/test_live.py — status + create/list/delete workspace round-trip; skipped unless GEO_RUN_INTEGRATION=1.
  • tests/evals/geo_eval.xml — read-only eval questions against GeoServer's standard sample data (e.g. topp:states has 49 features). Confirm the expected answers on your live instance.

Agent tools (28 geo_* functions)

These are the tools the agent calls internally to fulfil a request (they are not exposed individually over MCP — the agent is). make tools lists them.

Tool Kind Description
geo_get_status read Version + connectivity (/rest/about/version.json)
geo_list_workspaces read List workspaces
geo_get_workspace read Get one workspace
geo_create_workspace write Create workspace (optionally default)
geo_delete_workspace destructive Delete workspace (recurse)
geo_list_datastores read List datastores in a workspace
geo_get_datastore read Get one datastore
geo_create_datastore_postgis write Create a PostGIS datastore
geo_delete_datastore destructive Delete datastore (recurse)
geo_list_featuretypes read List feature types (or available tables)
geo_publish_featuretype write Publish a table as a layer (recalculates bbox)
geo_list_layers read List layers
geo_get_layer read Get one layer
geo_get_layer_bbox read Layer bounding boxes + SRS
geo_update_layer idempotent Set default style / enabled flag
geo_delete_layer destructive Delete layer (+ feature type cleanup)
geo_list_styles read List styles
geo_get_style read Get style SLD
geo_create_style write Create style from SLD string/file
geo_update_style idempotent Replace style SLD
geo_assign_style_to_layer idempotent Assign style to layer (default/extra)
geo_delete_style destructive Delete style (purge)
geo_wms_get_capabilities read WMS GetCapabilities
geo_wms_get_map read Build WMS GetMap URL (optionally download PNG)
geo_wfs_get_capabilities read WFS GetCapabilities
geo_wfs_get_feature read WFS GetFeature → GeoJSON (bbox or CQL)
geo_wfs_transaction write WFS-T delete / update / raw
geo_build_web_map read Generate a Leaflet HTML map (OSM + WMS overlays)

The agent's instructions (agent.py) tell it to treat delete_* as destructive and only run them on explicit request.

Resilience knobs

  • Retry with linear backoff on connect errors, timeouts, and HTTP 502/503/504 — controlled by GEOSERVER_RETRIES and GEOSERVER_RETRY_BACKOFF.
  • Actionable errors: 401/403/404/405/409/500 are translated into messages with a suggested fix.
  • OGC exceptions: ServiceExceptionReport / ServiceException (which arrive with HTTP 200) are detected and raised with the response body.
  • Logging on the mcp_geo_server logger (set GEO_LOG_LEVEL=DEBUG).

Project layout

src/mcp_geo_server/   core: config, client, formatting, agent (Agent Framework),
                      server (MCP stdio/http), tools/ (geo_* functions), templates/
webui/                FastAPI backend (app.py) + static Leaflet UI (static/index.html)
tests/                unit, behavioural, integration, evals
Dockerfile            app image (web UI + MCP agent)
docker-compose.yml    GeoServer 2.28.0 + PostGIS 16-3.4 + Ollama + webui + mcp

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选