# MapIt — interactive globe for highlighting geographic keypoints MapIt renders a set of geographic points (locations with labels + metadata) as glowing markers on an interactive 3D globe. Use it when you need to **map, plot, or visualize places / sites / locations** and hand a person a link they can explore. It is 100% client-side: there is no API to POST to and nothing is stored on the server. You build a URL that carries the data in its fragment, and the browser renders it. This is intentional — the server just serves static files. ## How to build a map URL 1. Make a payload: ```json { "title": "Customer sites", "options": { "marker_color": "#c07b74", "projection": "globe" }, "points": [ { "lat": 35.99, "lon": -78.90, "label": "Durham HQ", "meta": { "staff": 40 } }, { "place": "Tokyo, Japan", "label": "APAC office", "meta": { "region": "APAC" } } ] } ``` - Each point is either `{ "lat": , "lon": }` (renders instantly) or `{ "place": "City, Country" }` / `{ "city": "...", "country": "..." }` (geocoded in the browser via OpenStreetMap — prefer lat/lon when you have it). - `label` is the marker name; `meta` is any key/values, shown on hover. - A point may also set `color` (hex), `size`, and `images` (a list of public https photo URLs, shown as a swipeable strip in the tap card). - `options` is optional. `marker_color` is a hex string (map-wide default). `connect: true` draws arcs between consecutive points (a route), with an optional `arc_color`. `labels: true|false` forces marker text labels on/off (default: shown for small maps of <=15 points). `auto_rotate: false` freezes the globe framed on your data (best if you'll screenshot it; default is a spinning globe). - Points that can't be geocoded are skipped and reported in-app, not silently placed at (0,0). 2. Encode it and append to the base URL: ``` url = "https://jeddoman.com/mapit/#d=" + base64url( gzip( utf8( json(payload) ) ) ) ``` (strip base64 `=` padding). The `#d=` fragment is never sent to the server. Python: ```python import gzip, base64, json enc = base64.urlsafe_b64encode(gzip.compress(json.dumps(payload).encode())).decode().rstrip("=") url = "https://jeddoman.com/mapit/#d=" + enc ``` A ready-made builder is in the repo: `builders/mapit_url.py` (`build_map_url(points, title=..., marker_color=...)`). ## MCP tool For agents that speak MCP, the same thing is exposed as a tool `create_map` (see `mcp/` in the repo): `create_map(points, title="", marker_color=None, auto_rotate=True, connect=False, labels=None, arc_color="")` returns `{ "map_url": ... }`. It runs locally (stdio), builds the URL, and costs the server nothing. ## Examples Copy the pattern that matches the task. (These are `create_map` calls; if you build the URL directly, the same fields go in the payload's `points`/`options`.) Drop a single pin ("where is X?"): ```python create_map(points=[{"lat": 35.99, "lon": -78.90, "label": "Durham HQ"}]) ``` Several sites, with details shown on hover: ```python create_map( title="US offices", points=[ {"lat": 40.71, "lon": -74.01, "label": "New York", "meta": {"staff": 120, "opened": 2015}}, {"place": "Austin, Texas", "label": "Austin", "meta": {"staff": 45, "opened": 2021}}, ], ) ``` A route — points in order, connected by arcs, framed still for a clean shot: ```python create_map( title="Delivery route", connect=True, arc_color="#6a9a72", auto_rotate=False, points=[ {"lat": 51.51, "lon": -0.13, "label": "London"}, {"lat": 48.85, "lon": 2.35, "label": "Paris"}, {"lat": 52.52, "lon": 13.41, "label": "Berlin"}, ], ) ``` Two groups, distinguished by per-point color: ```python create_map( title="Supply network", points=[ {"lat": 37.77, "lon": -122.42, "label": "SF — customer", "color": "#6a9a72"}, {"lat": 40.71, "lon": -74.01, "label": "NYC — supplier", "color": "#c07b74"}, {"lat": 41.88, "lon": -87.63, "label": "Chicago — supplier", "color": "#c07b74"}, ], ) ``` Points with photos (image URLs must be public + https): ```python create_map( title="Property tour", points=[ {"lat": 37.77, "lon": -122.42, "label": "Loft", "images": ["https://example.com/loft1.jpg", "https://example.com/loft2.jpg"], "meta": {"price": "$2,400/mo"}}, ], ) ``` Screenshot-ready still map with labels always on: ```python create_map( title="APAC sites", auto_rotate=False, labels=True, points=[ {"lat": 35.68, "lon": 139.65, "label": "Tokyo"}, {"lat": 1.35, "lon": 103.82, "label": "Singapore"}, {"lat": -33.87, "lon": 151.21, "label": "Sydney"}, ], ) ``` ## Notes - Best for a handful to low-hundreds of keypoints. For very large sets, host a CSV/JSON yourself and pass `?data_url=` (that host must allow CORS). - There is no static-image endpoint by design; to embed a picture, open the URL and screenshot it with your own browser/harness. - Point `images` must be public `https` URLs the browser can fetch. Local files and non-public links won't load — upload photos to a public host first. MapIt never stores images; it just renders the URLs you give it.