Agent Native

add-geolocation

This skill sets up native background GPS tracking in Power Apps using the @microsoft/power-apps-native-bglocation package.

by MicrosoftOfficial publisherNot reviewed

Identity proven by GitHub's verified organisation badge (microsoft)

Agents
Claude Code
License
MIT (permissive)
Pin
ca144d2pinned Oct 9, 2026
Context cost
about 1,800 tokenswhen the skill loads
GitHub stars
978on microsoft/power-platform-skills
Scripts
None found

What it does

“Internal implementation skill invoked by /add-native for native background GPS tracking with durable storage and Dataverse sync using @microsoft/power-apps-native-bglocation.”
The author's description, from SKILL.md

Generated summary from the skill's own text

This skill sets up native background GPS tracking in Power Apps using the @microsoft/power-apps-native-bglocation package. It verifies the Dataverse target table and required columns exist, creates a TypeScript wrapper module, and configures MSAL authentication for continuous location recording with offline storage and Dataverse sync.

When to use it

  • Apps requiring continuous background GPS location tracking with native storage
  • Projects shipping the native geolocation package already installed
  • Need Dataverse integration for location records with offline capability
  • Configuration with trackInBackground and persistAcrossRestarts flags required

When not to

  • Single foreground coordinate reads; use location skill instead
  • Custom Dataverse tables or field mappings needed instead of defaults
  • Auth methods other than MSAL required for geolocation

Install

These commands install from the publisher's repository and need no account.

skills CLI

npx skills add microsoft/power-platform-skills --skill add-geolocation

Installs from the repository's default branch, which may have changed since the commit we checked.

GitHub CLI 2.90 or later

gh skill install microsoft/power-platform-skills add-geolocation@ca144d29c1665a329ab4b8e14946b2105e7622fa

Installs the commit we checked (ca144d2).

Copy by hand

Download the folder at ca144d2 and put it in .claude/skills/add-geolocation for Claude Code and in .agents/skills/add-geolocation for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.

Skill folder on GitHub at ca144d2

Claude Code plugin

/plugin install azure-cosmos-db-assistant@claude-plugins-official

The publisher's plugin in Claude's official marketplace. It may hold more than this skill, and we have not pinned it.

Claude Code plugin

/plugin install azure@claude-plugins-official

The publisher's plugin in Claude's official marketplace. It may hold more than this skill, and we have not pinned it.

Claude Code plugin

/plugin install azure-sql-developer@claude-plugins-official

The publisher's plugin in Claude's official marketplace. It may hold more than this skill, and we have not pinned it.

Copy for your agent

A prompt for any coding agent. It installs this skill from GitHub at the pinned commit, copies the files as they are, and runs nothing unless you ask.

Prompt

Install the agent skill "add-geolocation" by Microsoft.

Source, pinned to commit ca144d29c1665a329ab4b8e14946b2105e7622fa:
https://github.com/microsoft/power-platform-skills/tree/ca144d29c1665a329ab4b8e14946b2105e7622fa/plugins/mobile-apps/skills/add-native/add-geolocation

1. Download that folder at exactly this commit. Do not use the default branch.
2. Copy every file unchanged, keeping the folder structure, into .claude/skills/add-geolocation/ for Claude Code and .agents/skills/add-geolocation/ for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. Create the folders if they do not exist.
3. Do not edit the files, and do not run any script in the folder unless I ask you to.
4. When you are done, list the files you copied and where you put them.

Listing and checks: https://www.agentnative.dev/skills/microsoft/add-geolocation

SKILL.md at the pin

---
name: add-geolocation
description: Internal implementation skill invoked by /add-native for native background GPS tracking with durable storage and Dataverse sync using @microsoft/power-apps-native-bglocation.
user-invocable: false
disable-model-invocation: true
allowed-tools: Read, Edit, Write, Grep, Glob, Bash, AskUserQuestion
model: sonnet
---

**Shared instructions: [shared-instructions.md](${PLUGIN_ROOT}/shared/shared-instructions.md)** - read first.

# Add Geolocation

Internal helper for `/add-native geolocation`, `/add-native location-tracking`, `/add-native background-location`, `/add-native gps-tracking`, and `/add-native @microsoft/power-apps-native-bglocation`.

Use this only for continuous/background GPS tracking with native durable storage and inline Dataverse upload. For a single foreground coordinate read, use `/add-native location` (`expo-location`) instead.

Hard rules:
- Auth is MSAL-only. Do not expose OneAuth or an auth selector.
- Use `geoService(dataSource, app_id)` and `BgLocationClient`.
- Do not use `GeolocationExtension`, HostingSDK, PCF, Launch URI, or CordovaV2 bridge paths.
- Do not install packages or edit native config.
- The control is not usable until its Dataverse target table and mapped columns are verified.

## 1. Verify app and package

```bash
test -f app.config.js && test -f power.config.json && test -f package.json && test -d src
node -e "const p=require('./package.json'); const m='@microsoft/power-apps-native-bglocation'; if (!p.dependencies?.[m]) { console.error('MISSING: ' + m); process.exit(1); } console.log('OK: geolocation package present');"
```

If either check fails, stop. The template/app must already ship the native package.

## 2. Verify the Dataverse target table first

This control uses the package default Dataverse entity set:

```text
msdyn_locationrecords
```

Do not ask the user for a table name and do not invent a custom table. `msdyn_locationrecords` must already exist before the control can be used.

```bash
ENV_JSON=$(node "${PLUGIN_ROOT}/scripts/resolve-environment.js" "$(node -e "console.log(require('./power.config.json').environmentId)")")
ENV_URL=$(node -e "const j=JSON.parse(process.argv[1]); process.stdout.write(j.environmentUrl || '')" "$ENV_JSON")

TABLE="msdyn_locationrecords"
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "$ENV_URL" GET \
  "EntityDefinitions?\$filter=EntitySetName eq '$TABLE'&\$select=LogicalName,EntitySetName"
```

Required result:
- One row returned: capture `LogicalName` and verify columns.
- Empty `value: []`: stop. Mark `BLOCKED (target table missing)`. Do not create the table, do not route to `/add-dataverse`, and do not report the control as usable. Tell the user to run the geolocation-control table provisioning/setup mechanism, then re-run `/add-native geolocation`.
- Auth/environment error: stop. Mark `UNVERIFIED (target table not checked)`. Do not report the control as usable.

When the table exists, verify every mapped column exists:

```bash
node "${PLUGIN_ROOT}/scripts/dataverse-request.js" "$ENV_URL" GET \
  "EntityDefinitions(LogicalName='<logicalName>')/Attributes?\$select=LogicalName,AttributeType"
```

Required default `fieldMap` columns from the package README:

```text
msdyn_locationrecordid, msdyn_appid, msdyn_latitude, msdyn_longitude,
msdyn_altitude, msdyn_accuracy, msdyn_heading, msdyn_speed, msdyn_timestamp
```

If any active `fieldMap` column is missing, stop. Mark `BLOCKED (target columns missing)` and tell the user to fix the control table through the geolocation-control table provisioning/setup mechanism.

## 3. Write `src/native/geolocation.ts`

Create or patch `src/native/geolocation.ts` so screens import this wrapper, not the package directly.

The target config must require the README's two tracking flags:
- `trackInBackground: boolean`
- `persistAcrossRestarts: boolean`

```ts
// src/native/geolocation.ts
import {
  geoService,
  BgLocationClient,
  AuthMethod,
  ConnectionType,
} from '@microsoft/power-apps-native-bglocation';
import type {
  DataverseDataSource,
  LocationData,
  PermissionStatus,
} from '@microsoft/power-apps-native-bglocation';

export type { LocationData, PermissionStatus } from '@microsoft/power-apps-native-bglocation';

export type GeoTrackingTarget = Omit<DataverseDataSource, 'authMethod' | 'connectionType'>;

export type GeoResult<T> =
  | { ok: true; value: T }
  | {
      ok: false;
      reason: 'NATIVE_MODULE_MISSING' | 'PERMISSION_DENIED' | 'TRACKING_FAILED';
      message?: string;
    };

let activeClient: BgLocationClient | null = null;

function client(): BgLocationClient {
  return activeClient ?? new BgLocationClient();
}

function dataSource(target: GeoTrackingTarget): DataverseDataSource {
  return {
    ...target,
    authMethod: AuthMethod.MSAL,
    connectionType: ConnectionType.Dataverse,
  };
}

function fail(error: unknown): Extract<GeoResult<never>, { ok: false }> {
  const message = error instanceof Error ? error.message : String(error);
  if (/native|module|not.*link|undefined is not an object|null is not an object/i.test(message)) {
    return { ok: false, reason: 'NATIVE_MODULE_MISSING', message };
  }
  if (/permission|denied|authoriz|not granted/i.test(message)) {
    return { ok: false, reason: 'PERMISSION_DENIED', message };
  }
  return { ok: false, reason: 'TRACKING_FAILED', message };
}

export async function startTracking(
  app_id: string,
  target: GeoTrackingTarget,
): Promise<GeoResult<void>> {
  try {
    activeClient = geoService(dataSource(target), app_id);
    await activeClient.startTracking();
    return { ok: true, value: undefined };
  } catch (error) {
    activeClient = null;
    return fail(error);
  }
}

export async function stopTracking(): Promise<GeoResult<void>> {
  try {
    await client().stopTracking();
    activeClient = null;
    return { ok: true, value: undefined };
  } catch (error) {
    return fail(error);
  }
}

export async function isTracking(): Promise<GeoResult<boolean>> {
  try {
    return { ok: true, value: await client().isTracking() };
  } catch (error) {
    return fail(error);
  }
}

export async function getPermissionStatus(): Promise<GeoResult<PermissionStatus>> {
  try {
    return { ok: true, value: await client().getPermissionStatus() };
  } catch (error) {
    return fail(error);
  }
}

export async function getCurrentLocation(): Promise<GeoResult<LocationData>> {
  try {
    return { ok: true, value: await client().getCurrentLocation() };
  } catch (error) {
    return fail(error);
  }
}
```

## 4. Usage shape

Screens must pass `connectionUrl`, `trackInBackground`, and `persistAcrossRestarts`. Do not pass `tableName` or `fieldMap`; the control uses the default `msdyn_locationrecords` table and default `msdyn_*` field map. `intervalMs`, `distanceFilterMeters`, and `notification` are optional.

```ts
const target: GeoTrackingTarget = {
  connectionUrl: 'https://org.crm.dynamics.com',
  trackInBackground: true,
  persistAcrossRestarts: false,
};

await startTracking('my-wrap-app', target);
```

## 5. Type-check and summary

```bash
npx --no-install tsc --noEmit
```

Only after table + columns are verified and TypeScript passes, report:

```text
Geolocation status : READY
Package present    : @microsoft/power-apps-native-bglocation
Wrapper            : src/native/geolocation.ts
Required config    : connectionUrl, trackInBackground, persistAcrossRestarts
Auth               : MSAL only
Target table       : <TABLE> verified
Native config      : not changed
```

If table verification failed, report `BLOCKED` or `UNVERIFIED` instead and do not update `memory-bank.md` as if the control is ready.

From microsoft/power-platform-skills at ca144d2, shown as plain text under its license: MIT (permissive). The license text is in LICENSE.

View SKILL.md on GitHub at ca144d2

Files

1 file, 7.7 KB in total. Each file has a sha256 in the pin's manifest; the first 12 characters are shown.

Skill folder on GitHub at ca144d2
All 50 skills from Microsoft

More from Microsoft

  • pull-requests

    This skill guides the agent in writing high-quality pull request descriptions following the Agent Framework repository template and in systematically handling…

    Claude Code, Codex, Cursor +4 · about 1.5K tokens · pinned 6 days ago

  • appinsights-instrumentation

    This skill provides guidance and reference materials for instrumenting webapps with Azure Application Insights across ASP.NET Core, Node.js, Python, and…

    Contains scripts

    Claude Code, Codex, Cursor +3 · about 840 tokens · pinned 6 days ago

  • azure-ai

    This skill enables agents to use Azure AI services including Search for full-text and vector queries, Speech for transcription and synthesis, OpenAI for…

    Claude Code, Codex, Cursor +4 · about 750 tokens · pinned 6 days ago

  • azure-diagnostics

    The skill diagnoses Azure production issues across App Service, Functions, Container Apps, AKS, VMs, and Messaging services using AppLens, Azure Monitor…

    Contains scripts

    Claude Code, Codex, Cursor +3 · about 1.6K tokens · pinned 6 days ago

  • add-camera

    This skill generates typed TypeScript wrappers for camera capture and image gallery selection in Power Apps mobile apps using Expo libraries.

    Claude Code · about 5.2K tokens · pinned 6 days ago

  • add-connector

    This skill adds Power Platform connectors to Expo/React Native mobile apps by discovering the connector, establishing a connection, generating service files…

    Claude Code · about 3.8K tokens · pinned 6 days ago

All Mobile skills
  • expo-app-intents

    This skill adds Apple App Intents to Expo apps, enabling Siri voice commands and Shortcuts automation through Swift declarations that dispatch to JavaScript…

    by ExpoOfficial publisher

    Claude Code, Codex, Cursor +4 · about 3.6K tokens · pinned 6 days ago

  • eas-app-stores

    This skill configures and executes iOS and Android app builds and store submissions using EAS, Expo's app distribution service.

    by ExpoOfficial publisher

    Claude Code, Codex, Cursor +3 · about 1.7K tokens · pinned 6 days ago

  • eas-simulator

    Runs a user's app on a remote iOS or Android simulator hosted on EAS cloud infrastructure, accessible from machines without local simulator support like Linux…

    by ExpoOfficial publisher

    Claude Code, Codex, Cursor +3 · about 6.3K tokens · pinned 6 days ago

  • eas-update

    Configures and publishes over-the-air JavaScript and asset updates using EAS Update and the EAS CLI.

    by ExpoOfficial publisher

    Claude Code, Codex, Cursor +3 · about 2.3K tokens · pinned 6 days ago

  • expo-animation

    This skill guides building animations in React Native and Expo apps using Reanimated, Gesture Handler, and Expo Router.

    by ExpoOfficial publisher

    Claude Code, Codex, Cursor +3 · about 4.6K tokens · pinned 6 days ago

  • expo-app-clip

    This skill adds an iOS App Clip target to an Expo project, creating a lightweight app experience invoked from URLs on your domain.

    by ExpoOfficial publisher

    Claude Code, Codex, Cursor +4 · about 2.3K tokens · pinned 6 days ago

The skills listed here are third-party software, collected from public GitHub repositories as a catalog of recent skills and provided as is. Agent Native does not write or control them and is not responsible for any harm, loss or damage caused by installing or using them. Labels and checks describe what we saw at one commit and are not a guarantee. Read a skill's files before you run it. Terms of use