Skip to content
Documentation menu
docs / view-links · raw .md

View links: agent answers on a map

A view link is a plan carried in a URL. An agent that plans a route, a day of stops or a whole fleet hands back one link instead of a table; whoever opens it sees the stops on a map at once, with each route redrawn by MapMap routing.

ini
https://mapmap.ai/view?p=<payload>

No key, no account and no SDK are needed to open one, and nothing is stored on our side: the link carries its whole plan. Open /view without a payload for the short version of this page.

How an agent gets one

From the MCP server. The MCP server tools that answer with a plan, route, plan_day and optimise_routes, are gaining a view_url field that holds a ready-made link, and a view_url_note in its place when a plan is too big to link. Pass the link on as the last line of the answer. Until that field ships, build the link yourself as below.

Built by hand. The payload is base64url (RFC 4648 section 5, no padding) of compact JSON in UTF-8:

json
{"v":1,"kind":"route","costing":"auto","routes":[{"stops":[
  {"lat":51.5309,"lon":-0.1233,"name":"Kings Cross"},
  {"lat":51.5033,"lon":-0.1196,"name":"London Eye"}]}]}
sh
P=$(printf '%s' "$JSON" | base64 | tr '+/' '-_' | tr -d '=\n')
echo "https://mapmap.ai/view?p=$P"

What it carries

FieldRule
v1.
kindroute (one route, the stops are its waypoints), plan (one route in visit order; a return to the start repeats the start as the last stop) or fleet (one route per vehicle).
costingauto, truck, bicycle, pedestrian or motor_scooter. Absent draws as auto.
truckWith costing: "truck" only: height_m, width_m, length_m, weight_t, hazmat, tunnel_code (an ADR 8.6.4 code such as C or B/D). The redraw applies them, so a truck link is redrawn as that truck.
depart_atISO 8601 with an offset, shown as written.
titleAt most 60 characters.
routesroute and plan: exactly 1. fleet: 1 to 6. Each has an optional label (at most 24 characters), 2 to 22 stops, and optional totals.
stops[]lat, lon (required); name (at most 40 characters), arrive (HH:MM, 24-hour local clock) and dwell_min (whole minutes) optional.
totalsdistance_m and duration_s as the agent planned them, for the whole plan or (on a route) for that vehicle. duration_s is travel time; dwell is not included.

Unknown fields are ignored, so a newer link still opens on an older page. A link that breaks a structural rule (the version, the kind, the number of routes or stops, a coordinate) does not open; an optional field that breaks its rule is left out, and a string over its limit is cut to it.

What it does not carry: no key, no email, no account, nothing about who made it. The stop coordinates and names, the title and the route labels are the whole of it, and anyone holding the link can read them. The query string is logged by the web host like any URL, so treat a view link as you would the stop list itself.

What the page shows

  • The stops at once, numbered per route, in each route's colour.
  • Each route redrawn now with MapMap routing for the declared vehicle, and its distance and time as redrawn now.
  • The agent's own totals as as planned, beside the redrawn figures and never in place of them. Routing is time-aware, so a redraw can differ from the moment the plan was made.
  • The stop list with arrival clocks and dwell times when the link has them.
  • A plain message when a route has no path for that vehicle, when the redraw is unavailable, or when the link cannot be read.

The 6,000 character cap

The whole URL is at most 6,000 characters. A plan over the cap is trimmed in this order, stopping as soon as it fits:

  1. arrival clocks are dropped,
  2. then dwell times,
  3. then names are shortened to 20 characters,
  4. then names are dropped.

A plan still over the cap gets no link; from the MCP server, view_url_note says so instead. A six-vehicle fleet of 22 stops each fits once its names are dropped.

Writing an encoder

Any link that follows the rules above opens. If you want your links to match MapMap's byte for byte (useful for caching and tests), encode canonically:

  • Keys in this order: v, kind, costing, truck (height_m, width_m, length_m, weight_t, hazmat, tunnel_code), depart_at, title, routes (label, stops, totals), totals. A stop is lat, lon, name, arrive, dwell_min; totals are distance_m, duration_s. Leave absent fields out rather than writing null.
  • Compact JSON, no whitespace outside strings; non-ASCII stays as UTF-8 and / is not escaped.
  • Numbers as the shortest decimal that round-trips, integers without a fraction (4, not 4.0), never an exponent, never -0.
  • Coordinates rounded to 5 decimal places, half away from zero; totals and dwell_min rounded to whole numbers.
  • Strings trimmed of surrounding whitespace; lengths count Unicode code points.

This plan:

json
{
  "v": 1,
  "kind": "plan",
  "costing": "truck",
  "truck": { "height_m": 4, "width_m": 2.55, "length_m": 16.5, "weight_t": 40, "hazmat": true, "tunnel_code": "C" },
  "depart_at": "2026-10-20T08:00:00+01:00",
  "title": "Brighton delivery round",
  "routes": [
    {
      "label": "Van 1",
      "stops": [
        { "lat": 50.8289, "lon": -0.1411, "name": "Brighton station", "arrive": "08:00" },
        { "lat": 50.8277, "lon": -0.1697, "name": "Hove Town Hall", "arrive": "08:09", "dwell_min": 10 },
        { "lat": 50.8397, "lon": -0.1466, "name": "Preston Park Rotunda Café", "arrive": "08:29", "dwell_min": 15 }
      ]
    }
  ],
  "totals": { "distance_m": 6881, "duration_s": 1122 }
}

encodes to exactly this link (open it):

ini
https://mapmap.ai/view?p=eyJ2IjoxLCJraW5kIjoicGxhbiIsImNvc3RpbmciOiJ0cnVjayIsInRydWNrIjp7ImhlaWdodF9tIjo0LCJ3aWR0aF9tIjoyLjU1LCJsZW5ndGhfbSI6MTYuNSwid2VpZ2h0X3QiOjQwLCJoYXptYXQiOnRydWUsInR1bm5lbF9jb2RlIjoiQyJ9LCJkZXBhcnRfYXQiOiIyMDI2LTEwLTIwVDA4OjAwOjAwKzAxOjAwIiwidGl0bGUiOiJCcmlnaHRvbiBkZWxpdmVyeSByb3VuZCIsInJvdXRlcyI6W3sibGFiZWwiOiJWYW4gMSIsInN0b3BzIjpbeyJsYXQiOjUwLjgyODksImxvbiI6LTAuMTQxMSwibmFtZSI6IkJyaWdodG9uIHN0YXRpb24iLCJhcnJpdmUiOiIwODowMCJ9LHsibGF0Ijo1MC44Mjc3LCJsb24iOi0wLjE2OTcsIm5hbWUiOiJIb3ZlIFRvd24gSGFsbCIsImFycml2ZSI6IjA4OjA5IiwiZHdlbGxfbWluIjoxMH0seyJsYXQiOjUwLjgzOTcsImxvbiI6LTAuMTQ2NiwibmFtZSI6IlByZXN0b24gUGFyayBSb3R1bmRhIENhZsOpIiwiYXJyaXZlIjoiMDg6MjkiLCJkd2VsbF9taW4iOjE1fV19XSwidG90YWxzIjp7ImRpc3RhbmNlX20iOjY4ODEsImR1cmF0aW9uX3MiOjExMjJ9fQ