PHPackages                             track-any-device/mcp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. track-any-device/mcp

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

track-any-device/mcp
====================

MCP server, tools, and support classes for the Track Any Device platform.

v0.1.2(2w ago)0121↓100%[7 issues](https://github.com/track-any-device/package-mcp/issues)MITPHPPHP ^8.3CI passing

Since May 23Pushed 6d agoCompare

[ Source](https://github.com/track-any-device/package-mcp)[ Packagist](https://packagist.org/packages/track-any-device/mcp)[ RSS](/packages/track-any-device-mcp/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (5)Dependencies (3)Versions (4)Used By (0)

track-any-device/mcp
====================

[](#track-any-devicemcp)

MCP (Model Context Protocol) server for the Track Any Device platform. Exposes fleet-tracking data — devices, locations, assignees, and sensor readings — to AI assistants via [`laravel/mcp`](https://github.com/laravel/mcp).

---

Requirements
------------

[](#requirements)

DependencyVersionPHP`^8.3`Laravel`^13.7``laravel/mcp``^0.7.0``track-any-device/core``^0.0.2``stancl/tenancy``^3.10` (host app must install)---

Installation
------------

[](#installation)

```
composer require track-any-device/mcp
```

### 1 — Publish and wire the MCP route

[](#1--publish-and-wire-the-mcp-route)

The package does not auto-register a route. Publish the route stub and add the server:

```
php artisan vendor:publish --tag=mcp-routes   # from laravel/mcp
```

Then in `routes/ai.php` (created by the above command, or created manually):

```
use Laravel\Mcp\Facades\Mcp;
use TrackAnyDevice\Mcp\Servers\PortalServer;

Mcp::web('/mcp', PortalServer::class)
    ->middleware(['web', 'auth']);
```

> **Tenant subdomains** — register a second entry inside your tenancy route group so the URL is the same path on each subdomain. The `McpScope` detects the active tenant automatically via `tenancy()->tenant`.

### 2 — Environment variables

[](#2--environment-variables)

No env vars are required by this package itself. The underlying `laravel/mcp` package publishes its own config (`config/mcp.php`) which controls OAuth, path prefixes, etc.

---

Auth flow
---------

[](#auth-flow)

Requests to `/mcp` must arrive with a valid **Laravel session cookie** (web middleware) or a **Sanctum / Passport bearer token** (add the appropriate auth guard middleware). The package calls `auth()->user()` and aborts with 401 if no authenticated user is found.

The same endpoint serves multiple roles — scoping is applied automatically:

ContextRoleWhat is visibleCentral host`Role::Admin`All devices across all tenants; SIM/GSM numbers includedCentral host`Role::User`Only devices the user purchased or follows (`user_id` + pivot)Central host`Role::TenantUser`Nothing (misconfiguration guard — returns empty)Tenant subdomain`Role::Admin` / `Role::TenantAdmin`All devices for that tenantTenant subdomain`Role::TenantUser`Devices on beats the user is assigned to---

Host-app contracts
------------------

[](#host-app-contracts)

This package depends on the following from `track-any-device/core`. Any breakage in these will cause runtime errors:

SymbolTypeUsed in`TrackAnyDevice\Core\Models\Device`Eloquent modelAll tools`Device::activeDeviceAssignment`Relationship`DeviceProjection`, `LocateAssigneeTool`, `ReadSensorTool``Device::activeBeatAssignment`Relationship`DeviceProjection``Device::effectiveSensorSlugs(): array`Method`ReadSensorTool``TrackAnyDevice\Core\Models\Assignee`Eloquent model`LocateAssigneeTool`, `ReadSensorTool``Assignee::activeDeviceAssignment`Relationship`LocateAssigneeTool`, `ReadSensorTool``TrackAnyDevice\Core\Models\Sensor`Eloquent model`ReadSensorTool``Sensor::displayLabel(): string`Method`ReadSensorTool``TrackAnyDevice\Core\Models\Signal`Eloquent / InfluxDB model`SignalProjection``TrackAnyDevice\Core\Services\BeatScope`Service class`McpScope``TrackAnyDevice\Core\Services\SignalService`Service class`SignalProjection``TrackAnyDevice\Core\Enums\Role`Backed enum`McpScope``Role::isCentralStaff(): bool`Method`McpScope``tenancy()` global helperstancl/tenancy`McpScope`---

MCP server
----------

[](#mcp-server)

### `PortalServer` — `src/Servers/PortalServer.php`

[](#portalserver--srcserversportalserverphp)

Single server class mounted at the configured URL. The same class is used on both the central host and every tenant subdomain — scoping is transparent to the AI client.

**Server instructions** (sent to the AI at connection time) describe:

- URL-based scoping rules
- SIM/GSM privacy rules
- Signal object shape

---

Tools
-----

[](#tools)

### Navigation: Device tools

[](#navigation-device-tools)

ToolNameDescription`CountDevicesTool``count_devices`How many devices are visible. Accepts optional `status` filter.`ListDevicesTool``list_devices`Paginated device list. Filters: `status`, `search` (name / IMEI / serial).`FindDeviceTool``find_device`Find a single device by IMEI, serial, name (partial), or numeric id. Returns device + latest Signal.### Navigation: Assignee &amp; sensor tools

[](#navigation-assignee--sensor-tools)

ToolNameDescription`LocateAssigneeTool``locate_assignee`Find an assignee by name or code, return their device's latest Signal location. Tenant only.`ReadSensorTool``read_sensor`Read a named sensor value (`level`, `temperature`, `battery_percent`, etc.) from an assignee's device. Tenant only.---

Signal object shape
-------------------

[](#signal-object-shape)

Every location/sensor response includes a `signal` key and a `parsing` key. The signal shape mirrors `TrackAnyDevice\Core\Models\Signal::toArray()`:

```
server_time      ISO-8601 UTC (Z suffix)
device_time      ISO-8601 UTC (Z suffix) — may be null
latitude         decimal degrees WGS84
longitude        decimal degrees WGS84
gps_fixed        bool — false = stale or LBS-derived coordinates
battery_percent  0–100
battery_voltage  mV
temperature      °C (custom sensor)
level            tank/water/material level (custom sensor; units defined by device type)
event_type       update | punch_in | punch_out | sos | alarm | online | offline | ...
source           snapshot |
extra            object — device-specific extra fields

```

A `source: "snapshot"` means InfluxDB had no recent data and the reading was synthesised from the device row's snapshot columns (`last_lat`, `last_lon`, `last_seen_at`).

---

Release workflow
----------------

[](#release-workflow)

Releases are created automatically by `.github/workflows/release.yml` on every push to `main`and can also be triggered manually.

### Conventional commit → version bump

[](#conventional-commit--version-bump)

Commit prefixBump`fix:`, `chore:`, `refactor:`, `docs:`, `test:`, `style:`, `perf:`**patch**`feat:`**minor**`feat!:`, `fix!:`, any type with `BREAKING CHANGE` footer**major**The workflow reads the latest git tag, increments the appropriate component, creates a new annotated tag, and publishes a GitHub Release with an auto-generated changelog of commits since the previous tag. If there are no new commits since the last tag, the job exits cleanly without creating a release.

### Manual release

[](#manual-release)

Go to **Actions → Release → Run workflow** and pick `patch`, `minor`, or `major`.

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance98

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

3

Last Release

15d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/83275f3144d4cc4092e54dd8d5acf6a048536f6d7e454d741ae82a61f904c737?d=identicon)[ahmadkokab](/maintainers/ahmadkokab)

---

Top Contributors

[![afaryab](https://avatars.githubusercontent.com/u/68786248?v=4)](https://github.com/afaryab "afaryab (5 commits)")

### Embed Badge

![Health badge](/badges/track-any-device-mcp/health.svg)

```
[![Health](https://phpackages.com/badges/track-any-device-mcp/health.svg)](https://phpackages.com/packages/track-any-device-mcp)
```

###  Alternatives

[markwalet/nova-modal-response

A Laravel Nova asset for Modal responses on an action.

17818.7k](/packages/markwalet-nova-modal-response)[crumbls/layup

A visual page builder plugin for Filament 5 — Divi-style grid layouts with extensible widgets.

591.7k1](/packages/crumbls-layup)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.2k](/packages/tomshaw-electricgrid)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
