skills/osm-routing/SKILL.md
Calculate routes (walk, bike, car) using free OSM APIs - OSRM and Valhalla
npx skillsauth add jcsaaddupuy/badrobots osm-routingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Calculate routes using OSRM (fast) and Valhalla (quality).
# Car route
curl "https://router.project-osrm.org/route/v1/car/LON1,LAT1;LON2,LAT2" | jq '.routes[0]'
# Example: 2.4427,48.8663 → 2.4285,48.8485
curl -s "https://router.project-osrm.org/route/v1/bike/2.4427,48.8663;2.4285,48.8485" | jq '.routes[0] | {distance_m: .distance, duration_sec: .duration}'
# Walking route with full geometry (for plotting on maps)
curl -s "https://router.project-osrm.org/route/v1/foot/2.4427,48.8663;2.4285,48.8485?overview=full&geometries=geojson" | jq '.routes[0].geometry'
# Returns GeoJSON coordinates: [[lon, lat], [lon, lat], ...]
# Pedestrian (best for walking)
curl -s -X POST "https://valhalla1.openstreetmap.de/route" \
-H "Content-Type: application/json" \
-d '{"locations":[{"lat":48.8663,"lon":2.4427},{"lat":48.8485,"lon":2.4285}],"costing":"pedestrian"}' | \
jq '.trip | {distance_m: .summary.length, duration_sec: .summary.time}'
Profiles: foot, car, bike
curl "https://router.project-osrm.org/route/v1/{profile}/{lon1},{lat1};{lon2},{lat2}"
# Returns GeoJSON polyline for plotting on maps
curl -s "https://router.project-osrm.org/route/v1/foot/{lon1},{lat1};{lon2},{lat2}?overview=full&geometries=geojson" | jq '.routes[0].geometry'
# Coordinates: [[lon, lat], [lon, lat], ...]
curl -s "https://router.project-osrm.org/route/v1/bike/2.4427,48.8663;2.4285,48.8485;2.3522,48.8530" | jq '.routes[0].legs[]'
curl "https://router.project-osrm.org/route/v1/car/2.4427,48.8663;2.4285,48.8485?overview=full&steps=true&alternatives=true&geometries=geojson"
curl -s "https://router.project-osrm.org/table/v1/bike/2.4427,48.8663;2.4285,48.8485;2.3522,48.8530" | jq '.distances'
curl -s "https://router.project-osrm.org/nearest/v1/car/2.4427,48.8663" | jq '.waypoints[0]'
Costing: pedestrian, bicycle, auto, taxi, bikeshare
curl -s -X POST "https://valhalla1.openstreetmap.de/route" \
-H "Content-Type: application/json" \
-d '{"locations":[{"lat":LAT1,"lon":LON1},{"lat":LAT2,"lon":LON2}],"costing":"pedestrian"}' | \
jq '.trip | {distance: .summary.length, time: .summary.time}'
curl -s -X POST "https://valhalla1.openstreetmap.de/route" \
-H "Content-Type: application/json" \
-d '{"locations":[{"lat":48.8663,"lon":2.4427},{"lat":48.8485,"lon":2.4285}],"costing":"bicycle","costing_options":{"bicycle":{"use_roads":0.0}}}' | \
jq '.trip.summary'
curl -s -X POST "https://valhalla1.openstreetmap.de/route" \
-H "Content-Type: application/json" \
-d '{"locations":[{"lat":48.8663,"lon":2.4427},{"lat":48.8485,"lon":2.4285}],"costing":"auto","costing_options":{"auto":{"toll_booth_factor":1000}}}' | \
jq '.trip.summary'
curl -s -X POST "https://valhalla1.openstreetmap.de/route" \
-H "Content-Type: application/json" \
-d '{"locations":[{"lat":48.8663,"lon":2.4427},{"lat":48.8485,"lon":2.4285}],"costing":"pedestrian"}' | \
jq '.trip.legs[].maneuvers[] | {instruction, distance: .distance.value, time: .time}'
curl -s -X POST "https://valhalla1.openstreetmap.de/route" \
-H "Content-Type: application/json" \
-d '{"locations":[{"lat":48.8663,"lon":2.4427},{"lat":48.8566,"lon":2.3522},{"lat":48.8485,"lon":2.4285}],"costing":"bicycle"}' | \
jq '.trip | {total_distance: .summary.length, legs: (.legs | length)}'
curl -s -X POST "https://valhalla1.openstreetmap.de/isochrone" \
-H "Content-Type: application/json" \
-d '{"locations":[{"lat":48.8663,"lon":2.4427}],"costing":"bicycle","contours":[{"time":15}]}' | \
jq '.features[0].geometry'
| Use | API | Command |
|-----|-----|---------|
| Walking route (geometry for maps) | OSRM | GET /route/v1/foot/...?overview=full&geometries=geojson |
| Quick car | OSRM | GET simple |
| Pedestrian (detailed) | Valhalla | POST pedestrian |
| Bike avoid roads | Valhalla | POST + options |
| Multiple points | OSRM | table |
| Directions | Valhalla | maneuvers |
OSRM=$(curl -s "https://router.project-osrm.org/route/v1/bike/2.4427,48.8663;2.4285,48.8485" | jq '.routes[0].distance')
VALHALLA=$(curl -s -X POST "https://valhalla1.openstreetmap.de/route" \
-H "Content-Type: application/json" \
-d '{"locations":[{"lat":48.8663,"lon":2.4427},{"lat":48.8485,"lon":2.4285}],"costing":"bicycle"}' | \
jq '.trip.summary.length')
echo "OSRM: ${OSRM}m | Valhalla: ${VALHALLA}m"
for loc in "48.8566:2.3522" "48.8485:2.4285"; do
IFS=':' read lat lon <<< "$loc"
TIME=$(curl -s "https://router.project-osrm.org/route/v1/bike/2.4427,48.8663;$lon,$lat" | jq '.routes[0].duration')
echo "$lat,$lon: ${TIME}s"
done | sort -t: -k2 -n
for mode in foot car bike; do
OSRM=$(curl -s "https://router.project-osrm.org/route/v1/$mode/2.4427,48.8663;2.4285,48.8485" | jq '.routes[0] | "\(.distance)m / \(.duration)s"')
echo "$mode: $OSRM"
done
for costing in pedestrian bicycle auto; do
VALHALLA=$(curl -s -X POST "https://valhalla1.openstreetmap.de/route" \
-H "Content-Type: application/json" \
-d "{\"locations\":[{\"lat\":48.8663,\"lon\":2.4427},{\"lat\":48.8485,\"lon\":2.4285}],\"costing\":\"$costing\"}" | \
jq '.trip.summary | "\(.length)m / \(.time)s"')
echo "$costing: $VALHALLA"
done
API Choice: OSRM fast/simple, Valhalla better pedestrian/bike/details Resources: OSRM | Valhalla | OSM Wiki
development
DuckDB patterns for JSON/JSONL analysis, array unnesting, and common gotchas. Use when querying JSON files, nested data, or encountering "UNNEST not supported here" errors.
development
Mealie recipe manager API: recipes, shopping lists, meal plans. Requires MEALIE_BASE_URL and MEALIE_API_KEY.
business
TimeWarrior time tracking: start/stop intervals, query durations by tag or issue, compute totals for issue tracker time reporting
development
Bookmark manager for saving, searching, and annotating web content. Use when: (1) saving a webpage for later reference, (2) searching previously saved bookmarks, (3) adding highlights/annotations to saved content, (4) user asks to 'bookmark this' or 'save this article'. Requires READECK_BASE_URL and READECK_API_KEY environment variables.