npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

android-mock-location-mcp

v0.3.0

Published

MCP server for Android mock location testing

Downloads

206

Readme

MCP Server — android-mock-location-mcp

MCP server that exposes 11 tools for controlling Android emulator GPS location. Sets mock locations via adb emu geo fix and supports geocoding and street-level routing through configurable providers.

See the root README for project overview and quick start.

Installation

The server is launched automatically by your MCP client — you don't run it directly. The installation method determines how the client finds and starts it.

npx (no install needed): Use npx -y android-mock-location-mcp as the command in your MCP client config. The client will download and run it automatically.

Global install: Pre-install the package so the client can launch it without download delay:

npm install -g android-mock-location-mcp

Build from source:

cd server
npm install
npm run build

Updating: npx caches packages after the first download. To force an update, temporarily change the command in your MCP client config to npx -y android-mock-location-mcp@latest and restart the client.

See the Configuration section below for how to set up your MCP client to launch the server.

Configuration

Environment Variables

| Variable | Description | Required | |----------|-------------|----------| | PROVIDER | Provider for geocoding + routing: osm (default), google, mapbox | No (defaults to osm) | | GOOGLE_API_KEY | Google Places + Routes API key | When PROVIDER=google | | MAPBOX_ACCESS_TOKEN | Mapbox Geocoding + Directions access token | When PROVIDER=mapbox |

Provider selection is resolved once at server startup. Changing PROVIDER or API keys requires restarting the MCP client (which restarts the server).

Set environment variables in your MCP client configuration:

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "android-mock-location-mcp": {
      "command": "npx",
      "args": ["-y", "android-mock-location-mcp"]
    }
  }
}

No API key required. Uses free Nominatim geocoding and OSRM routing (car profile only).

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "android-mock-location-mcp": {
      "command": "npx",
      "args": ["-y", "android-mock-location-mcp"],
      "env": {
        "PROVIDER": "google",
        "GOOGLE_API_KEY": "your-google-api-key"
      }
    }
  }
}

Prerequisites: Enable both the Places API (New) and Routes API in your Google Cloud project.

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "android-mock-location-mcp": {
      "command": "npx",
      "args": ["-y", "android-mock-location-mcp"],
      "env": {
        "PROVIDER": "mapbox",
        "MAPBOX_ACCESS_TOKEN": "your-mapbox-access-token"
      }
    }
  }
}

After editing the config, restart Claude Desktop to apply the changes (this restarts the MCP server automatically).

claude mcp add android-mock-location-mcp -- npx -y android-mock-location-mcp

No API key required. Uses free Nominatim geocoding and OSRM routing (car profile only).

GOOGLE_API_KEY=your-google-api-key
claude mcp add android-mock-location-mcp \
  -e PROVIDER=google \
  -e GOOGLE_API_KEY=$GOOGLE_API_KEY \
  -- npx -y android-mock-location-mcp

Prerequisites: Enable both the Places API (New) and Routes API in your Google Cloud project.

MAPBOX_ACCESS_TOKEN=your-mapbox-access-token
claude mcp add android-mock-location-mcp \
  -e PROVIDER=mapbox \
  -e MAPBOX_ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN \
  -- npx -y android-mock-location-mcp

To switch from one provider to another (e.g. osmgoogle), remove and re-add the server with new env vars, then restart Claude Code:

# 1. Remove existing server
claude mcp remove android-mock-location-mcp

# 2. Re-add with new provider
GOOGLE_API_KEY=your-google-api-key
claude mcp add android-mock-location-mcp \
  -e PROVIDER=google \
  -e GOOGLE_API_KEY=$GOOGLE_API_KEY \
  -- npx -y android-mock-location-mcp

# 3. Restart Claude Code (this restarts the MCP server automatically)

Provider selection is resolved once at server startup, so restarting is required for changes to take effect.

Providers

Google and Mapbox providers produce better results than the default OSM provider — more accurate geocoding, full routing profile support (car/foot/bike), and higher rate limits. Both offer free tiers.

| PROVIDER | Geocoding Service | Routing Service | Profiles Supported | API Key | Cost | | ------------- | --------------------------- | --------------- | ------------------ | ---------------------- | -------------------- | | osm (default) | Nominatim (OpenStreetMap) | OSRM | car only* | None | Free (rate-limited) | | google | Google Places API | Google Routes API | car, foot, bike | GOOGLE_API_KEY | Paid (free tier) | | mapbox | Mapbox Geocoding | Mapbox Directions | car, foot, bike | MAPBOX_ACCESS_TOKEN | Paid (free tier) |

*OSRM limitation: The public OSRM demo server (router.project-osrm.org) only supports the car profile. Requesting foot or bike silently returns a driving route. For walking/cycling routing, use google or mapbox.

Nominatim rate limit: The OSM Nominatim API is rate-limited to 1 request per second. When using the osm provider, the server hints the AI to resolve place names to coordinates itself and pass lat/lng directly.

Tool Reference

geo_list_devices

List connected Android emulators via ADB.

No parameters.


geo_connect_device

Connect to an Android emulator for mock location control. Only emulators are supported (e.g. emulator-5554). Locations are set via the emulator's geo fix command.

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | deviceId | string | yes | Emulator serial from geo_list_devices, e.g. emulator-5554 |


geo_set_location

Set emulator GPS to coordinates or any place name/address. Geocodes place names via the configured provider.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | lat | number | no | — | Latitude (-90 to 90) | | lng | number | no | — | Longitude (-180 to 180) | | place | string | no | — | Place name or address, e.g. 'Times Square', 'Tokyo Station' |

Provide either place or both lat/lng.


geo_simulate_route

Simulate movement along a route between two points at a given speed. Routes follow real streets via the configured routing provider. Falls back to straight-line if the provider fails.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | from | string | no | — | Starting place name or address | | to | string | no | — | Destination place name or address | | fromLat | number | no | — | Starting latitude | | fromLng | number | no | — | Starting longitude | | toLat | number | no | — | Destination latitude | | toLng | number | no | — | Destination longitude | | speedKmh | number | no | 60 | Speed in km/h | | trafficMultiplier | number | no | 1.0 | Traffic slowdown factor (e.g. 1.5 = 50% slower) | | profile | enum | no | car | Routing profile: car, foot, or bike |

Provide either from/to (place names) or fromLat/fromLng/toLat/toLng (coordinates) for each endpoint.

Starting location auto-resolve: If no from/fromLat/fromLng is provided, the tool automatically tries (in order): the last mock location, the emulator's current GPS position via geo_get_location, or returns an error asking the user for their starting location.

Routing Profiles

| Profile | Use for | Routes on | |---------|---------|-----------| | car (default) | Driving simulation | Roads, highways | | foot | Walking simulation | Sidewalks, pedestrian paths | | bike | Cycling simulation | Bike lanes, roads |

The AI should select profile based on user intent (e.g. "walk to" → foot, "drive to" → car).


geo_simulate_multi_stop

Simulate movement along a multi-stop route (e.g. delivery route, rideshare pickups). Routes between consecutive waypoints follow real streets. Each waypoint can have a dwell time (time spent stationary at the stop before continuing). Runs as one continuous 1 Hz simulation with no gaps between legs.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | waypoints | array | yes | — | Ordered list of waypoints (min 2). Each: { lat?, lng?, place?, dwellSeconds? } | | speedKmh | number | no | 60 | Travel speed between waypoints (km/h) | | trafficMultiplier | number | no | 1.0 | Traffic slowdown factor (e.g. 1.5 = 50% slower) | | profile | enum | no | car | Routing profile: car, foot, or bike |

Each waypoint object:

| Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | lat | number | no | — | Waypoint latitude | | lng | number | no | — | Waypoint longitude | | place | string | no | — | Waypoint place name or address | | dwellSeconds | number | no | 0 | Time to stay at this waypoint before continuing (seconds) |

Provide either place or both lat/lng per waypoint. If the first waypoint has no coordinates or place, the tool auto-resolves from the current mock location or emulator GPS position.


geo_simulate_jitter

Simulate GPS noise/jitter at a location for testing accuracy handling.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | lat | number | no | — | Center latitude | | lng | number | no | — | Center longitude | | place | string | no | — | Center place name or address | | radiusMeters | number | no | 10 | Jitter radius in meters | | pattern | enum | no | random | Jitter pattern: random, drift, urban_canyon | | durationSeconds | number | no | 30 | Duration in seconds |

Provide either place or both lat/lng.

Jitter Patterns

| Pattern | Behavior | |---------|----------| | random | Uniform random distribution within radius | | drift | Gradual movement in one direction | | urban_canyon | Alternating accurate (3m) and inaccurate (50-80m) fixes, simulating tall buildings |


geo_test_geofence

Test geofence enter/exit/bounce behavior at a location.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | lat | number | no | — | Geofence center latitude | | lng | number | no | — | Geofence center longitude | | place | string | no | — | Geofence center place name or address | | radiusMeters | number | no | 100 | Geofence radius in meters | | action | enum | no | enter | Geofence action: enter, exit, bounce | | bounceCount | number | no | 3 | Number of boundary crossings (for bounce action) |

Provide either place or both lat/lng.

Geofence Actions

| Action | Behavior | |--------|----------| | enter | Move from outside to inside the geofence | | exit | Move from inside to outside the geofence | | bounce | Cross the boundary bounceCount times |


geo_replay_gpx_kml

Replay a GPX or KML track file on the emulator. Auto-detects format from the XML content.

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | fileContent | string | no* | — | Raw GPX or KML file content (XML string) | | filePath | string | no* | — | Absolute path to a GPX or KML file on the host | | speedMultiplier | number | no | 1.0 | Playback speed multiplier for time-based replay (e.g. 2.0 = 2x faster) | | speedKmh | number | no | 60 | Travel speed for distance-based replay (km/h) |

*Provide either fileContent or filePath.

Replay Modes

| Mode | When used | Speed control | |------|-----------|---------------| | Time-based | GPX files with timestamps on ≥80% of trackpoints | speedMultiplier — preserves original speed profile | | Distance-based | KML files, or GPX without timestamps | speedKmh — constant speed along the track |

GPX support: Extracts <trkpt> elements from <trk>/<trkseg> with optional <ele> (elevation) and <time> (timestamp).

KML support: Extracts <coordinates> from <LineString> elements. Coordinate format is lng,lat,ele tuples separated by whitespace.


geo_stop

Stop any active location simulation.

No parameters.


geo_get_status

Get current connection and simulation status.

No parameters.


geo_get_location

Get the emulator's current GPS location (last known position from the emulator's location providers). Reads the location via adb shell dumpsys location. Use this to determine where the emulator is before simulating a route.

No parameters.

Returns the emulator's latitude and longitude if a recent GPS fix is available, along with accuracy (horizontal accuracy in meters) when provided. If the emulator has no location fix, the tool returns an error message — in that case, ask the user for their current location.

How It Works

The server sets emulator GPS location using adb emu geo fix, which updates the emulator's stored GPS state. The command format is:

geo fix <longitude> <latitude> [<altitude> [<satellites> [<velocity>]]]

Unlike geo nmea (which injects one-shot NMEA sentences), geo fix updates the emulator's internal state so the position persists across the emulator's 1 Hz GPS update loop.

The geo fix command is processed directly by the emulator's GPS simulation layer.

Source Structure

| File | Purpose | |------|---------| | src/index.ts | MCP server setup, all 11 tool definitions with Zod schemas | | src/emulator.ts | Emulator connection management, location setting via geo fix | | src/adb.ts | ADB command execution with timeouts, emulator validation | | src/geocode.ts | Geocoding providers: Nominatim, Google, Mapbox | | src/routing.ts | Routing providers: OSRM, Google Routes API, Mapbox Directions | | src/gpx-kml.ts | GPX/KML file parsing for track replay | | src/geo-math.ts | Haversine distance calculation | | src/fetch-utils.ts | Shared fetchWithTimeout helper |

Development

npm install       # Install dependencies
npm run build     # Compile TypeScript
npm run dev       # Watch mode (recompile on change)
npm start         # Run the server

The server communicates via stdio (MCP protocol). To test interactively, use the MCP Inspector.

Known Limitations

  • Emulators only. The server uses adb emu geo fix which only works with Android emulators. Physical devices are not supported.
  • Single emulator. The server connects to one emulator at a time. Calling geo_connect_device with a different serial disconnects the previous one and stops any active simulation.
  • Single simulation. Only one simulation (route, jitter, or geofence) runs at a time. Starting a new one stops the previous.

See also: provider-specific limitations in the Providers table above.

Adding a New Provider

Both src/geocode.ts and src/routing.ts use the same pattern:

  1. Implement the GeocodeProvider type (in geocode.ts) and/or RoutingProvider type (in routing.ts)
  2. Add a case to selectProvider() in the respective file
  3. Validate required env vars in the selectProvider() switch case
  4. Document the new env var in this README and in CLAUDE.md