Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MapControl (MC²)

Map Control × Model Context Protocol — a live, shareable web map that AI agents (and humans) drive from code.

Discord License Python MCP FastAPI MapLibre ESIP


Ask your AI assistant to "draw the burn scar over Los Alamos and fly the camera to it" — and watch it happen live in a browser tab. MapControl is a headless map server with a real-time MapLibre frontend: create maps, add GeoJSON and GeoTIFF overlays, animate the camera, switch basemaps and themes, take screenshots — over a Python SDK, a REST API, or the Model Context Protocol for Claude, Cline, and any other MCP client.

Think of it as the Star Trek computer's map console. You say the words; the map moves.

Why MapControl?

  • 🗺️ Live & shareable — every map is a URL. Open it anywhere; it updates in real time over WebSocket.
  • 🤖 Agent-native — a first-class MCP server (Streamable HTTP) mounted at /mcp. Point Claude Desktop, Claude.ai, Cline, or the OpenAI Agents SDK at it and start talking to your map.
  • 🐍 Typed Python SDK — the mapcontrol package gives you sessions, assets, styles, screenshots, and camera control in a few lines.
  • 🌍 Real geospatial data — GeoJSON features, styled polygons/lines/points, glyph markers, arcs, and GeoTIFF rasters rendered server-side with colormaps.
  • 🏔️ 3D terrain & globe — MapLibre globe with terrain tiles and sky, or classic 2D. Ballistic zoom animations included.
  • 📸 Screenshots — capture the current viewport to PNG, straight from a tool call.
  • 🎨 Basemaps & themes — OpenStreetMap, Esri Satellite, and Carto Dark work with zero keys; drop in a MapTiler key for vector streets, hybrid, topo, and dataviz styles. Light/dark themes throughout.
  • 🔐 Optional auth — self-issued signed scoped tokens for /mcp, plus a standalone OAuth-style authorization portal for multi-user deployments.

Architecture

   Claude / Cline / any MCP client          Python SDK (`mapcontrol`)        curl / your app
                 │                                     │                           │
                 ▼                                     ▼                           ▼
            MCP (/mcp) ────────────────────────► REST API ◄───────────────────────┘
                                                     │
                                          FastAPI server (sessions,
                                          assets, events, GeoTIFFs,
                                          screenshots, auth)
                                                     │
                                              WebSocket fan-out
                                                     │
                                                     ▼
                                        MapLibre GL frontend (live map,
                                        3D terrain, drawing tools)
Directory What it is
server/ FastAPI server — REST API, WebSocket hub, MCP server, GeoTIFF & screenshot services, auth portal
sdk/ mapcontrol — typed Python client SDK
examples/ Runnable demo scripts (shapes, terrain, glyphs, GeoTIFFs) + sample data
docs/ Guides — MCP integration, MCP Apps field guide, map-engine comparison
docs/vision/ Design docs — architecture, specification, roadmap, protocol notes
deploy/ Deployment helpers (local PyPI index for the SDK)

Quick start

1. Run the server

Docker (fastest):

docker compose up --build

Or from source:

cd server
pip install -e ".[dev]"
uvicorn mapcontrol_server.main:app --reload --port 8000

The server is at http://localhost:8000 — interactive API docs at /docs.

2. Drive a map from Python

cd sdk && pip install -e .
from mapcontrol import MapControl

mc = MapControl("http://localhost:8000")
session = mc.create_map(name="demo")
print(session.map_url)   # ← open this in a browser; it updates live

session.zoom_to(-122.42, 37.77, zoom=12)         # fly to San Francisco
session.add_polygon([[-122.5, 37.7], [-122.4, 37.7], [-122.4, 37.8]])
session.set_basemap("satellite")
session.set_theme("dark")

shot = session.take_screenshot()                  # PNG of the current view

3. Connect an AI assistant (MCP)

The MCP server is mounted in-process at /mcp (Streamable HTTP — the current MCP standard). Add it to any MCP client:

Cline / Claude Desktop (mcpServers config):

{
  "mcpServers": {
    "mapcontrol": {
      "url": "http://localhost:8000/mcp"
    }
  }
}

Then just ask:

"Create a map, add a red polygon around Austin, switch to satellite, and zoom to it."

See docs/mcp-integration.md for full setup guides (Claude Desktop, Cline, Claude.ai web, OpenAI Agents SDK) and transport details.

MCP tools

Tool What it does
create_map Create a live map and get its shareable URL
add_geojson Add styled GeoJSON features (polygons, lines, points, glyphs)
add_arc Add a great-circle arc between two points
add_geotiff Upload & render a GeoTIFF raster with a colormap
zoom Fly the camera — to coordinates, bounds, or assets (ballistic animation)
list_assets List everything on a map
update_style Restyle an existing asset
set_visibility Show / hide an asset
delete_asset Remove an asset
set_basemap Switch basemaps (OSM, satellite, dark, MapTiler styles…)
set_theme Light / dark theme
get_viewport Read the current camera position
take_screenshot Capture the current view to PNG

REST API

Method Endpoint Description
POST /api/maps Create a map
GET /api/maps/{id} Get map info
DELETE /api/maps/{id} Delete a map
POST /api/maps/{id}/sessions Create a user session
POST /api/maps/{id}/events Send a map command
GET /api/maps/{id}/events List events
GET /api/maps/{id}/assets List assets
PATCH /api/maps/{id}/assets/{aid} Update an asset
DELETE /api/maps/{id}/assets/{aid} Delete an asset
GET /map/{id} Map frontend (iframe-ready; ?ui=none for a chromeless embed)
WS /ws/{id}/{session} WebSocket for real-time events

Configuration

Everything lives in server/config.toml — host/port, session TTL, storage paths, default basemap/theme/terrain, and the full basemap catalog. Keyless basemaps (OSM, Esri Satellite, Carto Dark) work out of the box; set MAPTILER_API_KEY to unlock the MapTiler vector styles. Adding a new tile provider is a config-only change.

Optional auth for /mcp is controlled via environment (MAPCONTROL_AUTH_MODE) — see server/mapcontrol_server/portal/ for the standalone authorization portal.

Demos

Runnable scripts in examples/ show the SDK end to end (start the server first):

python examples/demo.py                    # tour: shapes, styles, zoom, basemaps
python examples/demo_terrain_showcase.py   # 3D terrain + ballistic camera moves
python examples/demo_glyphs.py             # glyph markers & labels
# see also: demo_drawing.py, demo_ballistic_zoom.py, demo_multi_session.py

Sample GeoTIFFs live in examples/data/.

Running tests

cd server
pip install -e ".[dev]"
pytest tests/ -v

Community

Questions, ideas, demos to show off? Join us on Discord →

MapControl is developed within the ESIP Federation community. Issues and pull requests are welcome.

License

Apache-2.0