Lightweight client for connecting to GIS MCP servers to perform geospatial operations
Project description
GIS MCP Client
Lightweight Python client that connects to remote GIS MCP servers via SSE (Server-Sent Events) to enable agentic AI operations on the cloud. Perform geospatial operations remotely without installing heavy GIS libraries.
Features
- 🔹 Lightweight - No heavy GIS libraries required, just MCP client dependencies
- 🔹 SSE Connection - Connects to remote GIS MCP servers via Server-Sent Events for real-time agentic AI operations
- 🔹 Cloud-Based - Perform agentic AI operations on the cloud without local GIS dependencies
- 🔹 HTTP & SSE Support - Connect via HTTP or Server-Sent Events
- 🔹 Remote Storage - Upload/download files to/from remote server storage
- 🔹 Authentication - Support for token-based and basic authentication
- 🔹 Easy to Use - Simple API for calling remote GIS operations
Installation
pip install gis-mcp-client
Quick Start
See the examples for runnable code.
Examples
upload_only.py (RemoteStorage upload)
import os
from pathlib import Path
from gis_mcp_client import RemoteStorage
def main() -> None:
base = os.getenv("GIS_MCP_BASE", "http://localhost:9010").rstrip("/")
storage_url = os.getenv("GIS_STORAGE_URL", f"{base}/storage")
token = os.getenv("GIS_MCP_TOKEN")
local_file = os.getenv("GIS_INPUT_FILE")
if not local_file:
raise SystemExit("Set GIS_INPUT_FILE to the local path you want to upload.")
remote_name = os.getenv("GIS_REMOTE_OUTPUT") or Path(local_file).name
storage = RemoteStorage(
storage_endpoint=storage_url,
credentials={"token": token} if token else None,
)
result = storage.upload(local_file, remote_name)
if not result.get("success"):
raise SystemExit(f"Upload failed: {result.get('message')}")
print(f"Uploaded '{local_file}' -> remote path '{result['remote_path']}'")
if __name__ == "__main__":
main()
langchain_openrouter_buffer_simple.py (LangChain + OpenRouter buffer)
import asyncio, os
from langchain.agents import create_agent
from langchain_core.messages import AIMessage
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import MultiServerMCPClient
from gis_mcp_client import GISMCPClient
OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1"
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
MCP_SERVER_URL = os.getenv("MCP_SERVER_URL", "http://localhost:9010/sse")
GIS_MCP_TOKEN = os.getenv("GIS_MCP_TOKEN")
MODEL_NAME = os.getenv("MODEL_NAME", "deepseek/deepseek-chat-v3.1")
SYSTEM_PROMPT = "You are a helpful GIS agent using remote MCP tools."
def init_llm() -> ChatOpenAI:
if not OPENROUTER_API_KEY:
raise RuntimeError("OPENROUTER_API_KEY is required.")
return ChatOpenAI(model=MODEL_NAME, api_key=OPENROUTER_API_KEY, base_url=OPENROUTER_BASE_URL, temperature=0.2)
def init_mcp() -> MultiServerMCPClient:
gis_client = GISMCPClient(
server_url=MCP_SERVER_URL,
transport="auto",
credentials={"token": GIS_MCP_TOKEN} if GIS_MCP_TOKEN else None,
)
tool_spec = gis_client.as_mcp_tool(server_label="gis-mcp")
return MultiServerMCPClient({
"gis": {
"transport": "sse",
"url": tool_spec["server_url"],
"headers": tool_spec["server_headers"],
}
})
async def main() -> None:
llm = init_llm()
mcp_client = init_mcp()
tools = await mcp_client.get_tools()
agent = create_agent(model=llm, tools=tools, system_prompt=SYSTEM_PROMPT)
user_prompt = (
"Call the GIS MCP 'buffer' tool and return the buffered geometry. "
f"Use geometry POINT(0 0), distance 1000, resolution 16."
)
res = await agent.ainvoke({"messages": [{"role": "user", "content": user_prompt}]})
msgs = res.get("messages", [])
final = next(
(m.content for m in reversed(msgs) if isinstance(m, AIMessage)),
msgs[-1].content if msgs else "No response",
)
print("Agent response:\n", final)
if __name__ == "__main__":
asyncio.run(main())
API Reference
GISMCPClient
Main client for connecting to GIS MCP servers.
Methods
list_tools()- List all available toolscall_tool(name, arguments)- Call a remote toolget_tool_info(name)- Get information about a specific toolconnect_sse()- Connect via Server-Sent Events
RemoteStorage
Client for managing remote storage.
Methods
upload(local_path, remote_path)- Upload a filedownload(remote_path, local_path)- Download a filelist_files(remote_path)- List files in storage
Requirements
- Python 3.10+
mcp- MCP protocol clientrequests- HTTP clientsseclient-py- Server-Sent Events support
License
MIT License - see LICENSE file for details.
Related Projects
- GIS MCP Server - The server this client connects to
- See
examples/agentic_any_library.pyfor an end-to-end agent bridge example.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gis_mcp_client-0.1.1.tar.gz.
File metadata
- Download URL: gis_mcp_client-0.1.1.tar.gz
- Upload date:
- Size: 7.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40b737e1f408135b4bece259612b0b3f7eb0aebe3f48226b275ba7249b39af3a
|
|
| MD5 |
b09917b820936f442e5b7975a7b1ec30
|
|
| BLAKE2b-256 |
90fac2402aed9ac40f2961c217ed5150cb12eefef13f7513660cbca57b4dd374
|
File details
Details for the file gis_mcp_client-0.1.1-py3-none-any.whl.
File metadata
- Download URL: gis_mcp_client-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
faa6c67a550dd0b811a1c002fdeb3a8f4ab895adaf5ca1be94fe73a2e5ec4bcd
|
|
| MD5 |
1ad1dc6b3be469f9020bbbdd0d2c69e8
|
|
| BLAKE2b-256 |
99de6c0c737d2a9232eccf03bc235d5eba6cb522112881dcc3a0170f9f284a34
|