android-mock-location-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -0
- package/dist/device.d.ts +10 -0
- package/dist/device.js +154 -0
- package/dist/device.js.map +1 -0
- package/dist/fetch-utils.d.ts +5 -0
- package/dist/fetch-utils.js +16 -0
- package/dist/fetch-utils.js.map +1 -0
- package/dist/geo-math.d.ts +4 -0
- package/dist/geo-math.js +20 -0
- package/dist/geo-math.js.map +1 -0
- package/dist/geocode.d.ts +7 -0
- package/dist/geocode.js +101 -0
- package/dist/geocode.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +428 -0
- package/dist/index.js.map +1 -0
- package/dist/routing.d.ts +32 -0
- package/dist/routing.js +263 -0
- package/dist/routing.js.map +1 -0
- package/package.json +45 -0
package/dist/routing.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// ── Routing ──────────────────────────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Provides street-level routing for route simulation. The active provider is
|
|
4
|
+
// selected via the PROVIDER environment variable (shared with geocoding):
|
|
5
|
+
//
|
|
6
|
+
// PROVIDER=osm (default, free, no API key — Nominatim + OSRM)
|
|
7
|
+
// PROVIDER=google (requires GOOGLE_API_KEY)
|
|
8
|
+
// PROVIDER=mapbox (requires MAPBOX_ACCESS_TOKEN)
|
|
9
|
+
//
|
|
10
|
+
// NOTE: The OSRM public demo server (router.project-osrm.org) only supports
|
|
11
|
+
// the "car" profile. Requesting "foot" or "bike" silently returns a driving
|
|
12
|
+
// route. For proper walking/cycling routing, use Google or Mapbox providers,
|
|
13
|
+
// or self-host OSRM with foot/bike profiles loaded.
|
|
14
|
+
//
|
|
15
|
+
// To add a new provider, implement the RoutingProvider signature and add a
|
|
16
|
+
// case to selectProvider().
|
|
17
|
+
import { haversineDistance, computeBearing } from "./geo-math.js";
|
|
18
|
+
import { fetchWithTimeout } from "./fetch-utils.js";
|
|
19
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
20
|
+
function buildCumulativeDistances(points) {
|
|
21
|
+
const dists = [0];
|
|
22
|
+
for (let i = 1; i < points.length; i++) {
|
|
23
|
+
dists.push(dists[i - 1] + haversineDistance(points[i - 1].lat, points[i - 1].lng, points[i].lat, points[i].lng));
|
|
24
|
+
}
|
|
25
|
+
return dists;
|
|
26
|
+
}
|
|
27
|
+
function buildStraightLineRoute(fromLat, fromLng, toLat, toLng) {
|
|
28
|
+
const points = [
|
|
29
|
+
{ lat: fromLat, lng: fromLng },
|
|
30
|
+
{ lat: toLat, lng: toLng },
|
|
31
|
+
];
|
|
32
|
+
const dist = haversineDistance(fromLat, fromLng, toLat, toLng);
|
|
33
|
+
return {
|
|
34
|
+
points,
|
|
35
|
+
distanceMeters: dist,
|
|
36
|
+
cumulativeDistances: [0, dist],
|
|
37
|
+
source: "straight-line",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// ── OSRM Provider ────────────────────────────────────────────────────────────
|
|
41
|
+
const OSRM_PROFILES = {
|
|
42
|
+
car: "car",
|
|
43
|
+
foot: "foot",
|
|
44
|
+
bike: "bicycle",
|
|
45
|
+
};
|
|
46
|
+
const osrmRouting = async (fromLat, fromLng, toLat, toLng, profile) => {
|
|
47
|
+
const osrmProfile = OSRM_PROFILES[profile];
|
|
48
|
+
const url = `https://router.project-osrm.org/route/v1/${osrmProfile}/` +
|
|
49
|
+
`${fromLng},${fromLat};${toLng},${toLat}?overview=full&geometries=geojson`;
|
|
50
|
+
const res = await fetchWithTimeout(url, {
|
|
51
|
+
headers: { "User-Agent": "android-mock-location-mcp/0.1.0" },
|
|
52
|
+
}, 10_000);
|
|
53
|
+
if (!res.ok)
|
|
54
|
+
return null;
|
|
55
|
+
const data = (await res.json());
|
|
56
|
+
if (data.code !== "Ok" || !data.routes?.length)
|
|
57
|
+
return null;
|
|
58
|
+
const route = data.routes[0];
|
|
59
|
+
const coords = route.geometry.coordinates;
|
|
60
|
+
if (!coords.length)
|
|
61
|
+
return null;
|
|
62
|
+
// OSRM returns [lng, lat] (GeoJSON standard) — swap to {lat, lng}
|
|
63
|
+
const points = coords.map(([lng, lat]) => ({ lat, lng }));
|
|
64
|
+
const cumulativeDistances = buildCumulativeDistances(points);
|
|
65
|
+
return {
|
|
66
|
+
points,
|
|
67
|
+
distanceMeters: cumulativeDistances[cumulativeDistances.length - 1],
|
|
68
|
+
cumulativeDistances,
|
|
69
|
+
source: "osrm",
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
// ── Google Routes Provider ───────────────────────────────────────────────────
|
|
73
|
+
const GOOGLE_TRAVEL_MODES = {
|
|
74
|
+
car: "DRIVE",
|
|
75
|
+
foot: "WALK",
|
|
76
|
+
bike: "BICYCLE",
|
|
77
|
+
};
|
|
78
|
+
function decodeGooglePolyline(encoded) {
|
|
79
|
+
const points = [];
|
|
80
|
+
let index = 0;
|
|
81
|
+
let lat = 0;
|
|
82
|
+
let lng = 0;
|
|
83
|
+
while (index < encoded.length) {
|
|
84
|
+
let shift = 0;
|
|
85
|
+
let result = 0;
|
|
86
|
+
let byte;
|
|
87
|
+
do {
|
|
88
|
+
if (index >= encoded.length)
|
|
89
|
+
return points; // truncated input
|
|
90
|
+
byte = encoded.charCodeAt(index++) - 63;
|
|
91
|
+
result |= (byte & 0x1f) << shift;
|
|
92
|
+
shift += 5;
|
|
93
|
+
} while (byte >= 0x20);
|
|
94
|
+
lat += result & 1 ? ~(result >> 1) : result >> 1;
|
|
95
|
+
shift = 0;
|
|
96
|
+
result = 0;
|
|
97
|
+
do {
|
|
98
|
+
if (index >= encoded.length)
|
|
99
|
+
return points; // truncated input
|
|
100
|
+
byte = encoded.charCodeAt(index++) - 63;
|
|
101
|
+
result |= (byte & 0x1f) << shift;
|
|
102
|
+
shift += 5;
|
|
103
|
+
} while (byte >= 0x20);
|
|
104
|
+
lng += result & 1 ? ~(result >> 1) : result >> 1;
|
|
105
|
+
points.push({ lat: lat / 1e5, lng: lng / 1e5 });
|
|
106
|
+
}
|
|
107
|
+
return points;
|
|
108
|
+
}
|
|
109
|
+
const googleRouting = async (fromLat, fromLng, toLat, toLng, profile) => {
|
|
110
|
+
const apiKey = process.env.GOOGLE_API_KEY; // Validated by selectProvider()
|
|
111
|
+
const body = {
|
|
112
|
+
origin: { location: { latLng: { latitude: fromLat, longitude: fromLng } } },
|
|
113
|
+
destination: { location: { latLng: { latitude: toLat, longitude: toLng } } },
|
|
114
|
+
travelMode: GOOGLE_TRAVEL_MODES[profile],
|
|
115
|
+
};
|
|
116
|
+
const res = await fetchWithTimeout("https://routes.googleapis.com/directions/v2:computeRoutes", {
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers: {
|
|
119
|
+
"Content-Type": "application/json",
|
|
120
|
+
"X-Goog-Api-Key": apiKey,
|
|
121
|
+
"X-Goog-FieldMask": "routes.distanceMeters,routes.polyline.encodedPolyline",
|
|
122
|
+
},
|
|
123
|
+
body: JSON.stringify(body),
|
|
124
|
+
}, 10_000);
|
|
125
|
+
if (!res.ok)
|
|
126
|
+
return null;
|
|
127
|
+
const data = (await res.json());
|
|
128
|
+
const route = data.routes?.[0];
|
|
129
|
+
const encoded = route?.polyline?.encodedPolyline;
|
|
130
|
+
if (!encoded)
|
|
131
|
+
return null;
|
|
132
|
+
const points = decodeGooglePolyline(encoded);
|
|
133
|
+
if (points.length < 2)
|
|
134
|
+
return null;
|
|
135
|
+
const cumulativeDistances = buildCumulativeDistances(points);
|
|
136
|
+
return {
|
|
137
|
+
points,
|
|
138
|
+
distanceMeters: cumulativeDistances[cumulativeDistances.length - 1],
|
|
139
|
+
cumulativeDistances,
|
|
140
|
+
source: "google",
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
// ── Mapbox Directions Provider ───────────────────────────────────────────────
|
|
144
|
+
const MAPBOX_PROFILES = {
|
|
145
|
+
car: "driving",
|
|
146
|
+
foot: "walking",
|
|
147
|
+
bike: "cycling",
|
|
148
|
+
};
|
|
149
|
+
const mapboxRouting = async (fromLat, fromLng, toLat, toLng, profile) => {
|
|
150
|
+
const token = process.env.MAPBOX_ACCESS_TOKEN; // Validated by selectProvider()
|
|
151
|
+
const mapboxProfile = MAPBOX_PROFILES[profile];
|
|
152
|
+
const url = `https://api.mapbox.com/directions/v5/mapbox/${mapboxProfile}/` +
|
|
153
|
+
`${fromLng},${fromLat};${toLng},${toLat}?geometries=geojson&overview=full&access_token=${token}`;
|
|
154
|
+
const res = await fetchWithTimeout(url, {
|
|
155
|
+
headers: { "User-Agent": "android-mock-location-mcp/0.1.0" },
|
|
156
|
+
}, 10_000);
|
|
157
|
+
if (!res.ok)
|
|
158
|
+
return null;
|
|
159
|
+
const data = (await res.json());
|
|
160
|
+
if (data.code !== "Ok" || !data.routes?.length)
|
|
161
|
+
return null;
|
|
162
|
+
const route = data.routes[0];
|
|
163
|
+
const coords = route.geometry.coordinates;
|
|
164
|
+
if (!coords.length)
|
|
165
|
+
return null;
|
|
166
|
+
// Mapbox returns [lng, lat] (GeoJSON standard)
|
|
167
|
+
const points = coords.map(([lng, lat]) => ({ lat, lng }));
|
|
168
|
+
const cumulativeDistances = buildCumulativeDistances(points);
|
|
169
|
+
return {
|
|
170
|
+
points,
|
|
171
|
+
distanceMeters: cumulativeDistances[cumulativeDistances.length - 1],
|
|
172
|
+
cumulativeDistances,
|
|
173
|
+
source: "mapbox",
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
// ── Provider Selection ───────────────────────────────────────────────────────
|
|
177
|
+
// To switch providers, set PROVIDER env var to "osm", "google", or "mapbox".
|
|
178
|
+
function selectProvider() {
|
|
179
|
+
const name = (process.env.PROVIDER ?? "osm").toLowerCase();
|
|
180
|
+
switch (name) {
|
|
181
|
+
case "google": {
|
|
182
|
+
if (!process.env.GOOGLE_API_KEY) {
|
|
183
|
+
throw new Error("PROVIDER=google requires GOOGLE_API_KEY environment variable");
|
|
184
|
+
}
|
|
185
|
+
return googleRouting;
|
|
186
|
+
}
|
|
187
|
+
case "mapbox": {
|
|
188
|
+
if (!process.env.MAPBOX_ACCESS_TOKEN) {
|
|
189
|
+
throw new Error("PROVIDER=mapbox requires MAPBOX_ACCESS_TOKEN environment variable");
|
|
190
|
+
}
|
|
191
|
+
return mapboxRouting;
|
|
192
|
+
}
|
|
193
|
+
default:
|
|
194
|
+
return osrmRouting;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const activeProvider = selectProvider();
|
|
198
|
+
// ── Public API ───────────────────────────────────────────────────────────────
|
|
199
|
+
/**
|
|
200
|
+
* Fetch a street-level route. Falls back to straight-line if the provider fails.
|
|
201
|
+
*/
|
|
202
|
+
export async function getRoute(fromLat, fromLng, toLat, toLng, profile) {
|
|
203
|
+
try {
|
|
204
|
+
const result = await activeProvider(fromLat, fromLng, toLat, toLng, profile);
|
|
205
|
+
if (result)
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
// Provider failed — fall through to straight-line
|
|
210
|
+
}
|
|
211
|
+
return buildStraightLineRoute(fromLat, fromLng, toLat, toLng);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Interpolate a position along a route polyline at the given progress fraction (0–1).
|
|
215
|
+
*/
|
|
216
|
+
export function interpolateAlongRoute(route, fraction) {
|
|
217
|
+
if (fraction <= 0)
|
|
218
|
+
return route.points[0];
|
|
219
|
+
if (fraction >= 1)
|
|
220
|
+
return route.points[route.points.length - 1];
|
|
221
|
+
const targetDist = fraction * route.distanceMeters;
|
|
222
|
+
const cumDists = route.cumulativeDistances;
|
|
223
|
+
// Find the segment containing targetDist
|
|
224
|
+
let i = 0;
|
|
225
|
+
while (i < cumDists.length - 1 && cumDists[i + 1] <= targetDist) {
|
|
226
|
+
i++;
|
|
227
|
+
}
|
|
228
|
+
// Edge case: at or past the last point
|
|
229
|
+
if (i >= route.points.length - 1)
|
|
230
|
+
return route.points[route.points.length - 1];
|
|
231
|
+
const segStart = cumDists[i];
|
|
232
|
+
const segEnd = cumDists[i + 1];
|
|
233
|
+
const segLen = segEnd - segStart;
|
|
234
|
+
if (segLen === 0)
|
|
235
|
+
return route.points[i];
|
|
236
|
+
const segFrac = (targetDist - segStart) / segLen;
|
|
237
|
+
const p1 = route.points[i];
|
|
238
|
+
const p2 = route.points[i + 1];
|
|
239
|
+
return {
|
|
240
|
+
lat: p1.lat + (p2.lat - p1.lat) * segFrac,
|
|
241
|
+
lng: p1.lng + (p2.lng - p1.lng) * segFrac,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Compute bearing along the route polyline at the given progress fraction.
|
|
246
|
+
*/
|
|
247
|
+
export function bearingAlongRoute(route, fraction) {
|
|
248
|
+
if (route.points.length < 2)
|
|
249
|
+
return 0;
|
|
250
|
+
const clampedFrac = Math.max(0, Math.min(1, fraction));
|
|
251
|
+
const targetDist = clampedFrac * route.distanceMeters;
|
|
252
|
+
const cumDists = route.cumulativeDistances;
|
|
253
|
+
let i = 0;
|
|
254
|
+
while (i < cumDists.length - 1 && cumDists[i + 1] <= targetDist) {
|
|
255
|
+
i++;
|
|
256
|
+
}
|
|
257
|
+
if (i >= route.points.length - 1)
|
|
258
|
+
i = route.points.length - 2;
|
|
259
|
+
const p1 = route.points[i];
|
|
260
|
+
const p2 = route.points[i + 1];
|
|
261
|
+
return computeBearing(p1.lat, p1.lng, p2.lat, p2.lng);
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.js","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "android-mock-location-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for Android mock location testing",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"android-mock-location-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"prepare": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
18
|
+
"zod": "^3.25.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"typescript": "^5.8.0",
|
|
22
|
+
"@types/node": "^22.0.0"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"mcp",
|
|
26
|
+
"android",
|
|
27
|
+
"mock-location",
|
|
28
|
+
"gps",
|
|
29
|
+
"testing",
|
|
30
|
+
"location",
|
|
31
|
+
"model-context-protocol"
|
|
32
|
+
],
|
|
33
|
+
"author": "Manabu-GT (Manabu Shimobe)",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/Manabu-GT/android-mock-location-mcp.git"
|
|
37
|
+
},
|
|
38
|
+
"license": "Apache-2.0",
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist"
|
|
44
|
+
]
|
|
45
|
+
}
|