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

ituran-mcp

v4.2.0

Published

Stdio MCP server exposing the Ituran Global V2 API as MCP tools. Mints and refreshes its own access tokens via identity-server-v1 from credentials in env vars; tokens never reach the LLM.

Downloads

246

Readme

ituran-mcp

Stdio MCP server that exposes the Ituran Global V2 / Trips / BI & operational Reports / Safety / Maintenance / Advanced / ITC APIs as 152 MCP tool definitions (151 register with the degraded tool hidden; 120 register on the default read-only server, where the 7-tool maintenance family is opt-in). The server holds the user's long-lived credentials in env vars, mints its own access tokens against identity-server-v1, and refreshes them silently. Tokens never reach the LLM.

⚠️ Defaults to QA (https://api-qa.ituran.com/api/v2). Many tools mutate state (DELETE / PUT / PATCH / POST). To run against the production fleet set ITURAN_GLOBAL_BASE_URL=https://api.ituran.com/api/v2 explicitly.

Install

Published to the public npm registry as ituran-mcp — no auth, no registry config. Any MCP client with stdio-server support can launch it through npx.

Prerequisites

  • Node.js ≥ 20 (node -v)
  • An MCP client with stdio-server support (the example below uses Claude Code)
  • An Ituran service account without 2FA — password grant returns an OTP challenge that the MCP can't satisfy on its own. Use a non-OTP service account.

Step 1 — Register the MCP (Claude Code example)

The examples below register against QA (api-qa.ituran.com). Setting ITURAN_GLOBAL_BASE_URL explicitly — even to the default — is recommended so the environment is obvious in claude mcp get ituran. To switch to prod, see Switching to production.

Linux / macOS:

claude mcp add --scope user ituran \
  --env ITURAN_USERNAME='[email protected]' \
  --env ITURAN_PASSWORD='your-password' \
  --env ITURAN_GLOBAL_BASE_URL=https://api-qa.ituran.com/api/v2 \
  -- npx -y ituran-mcp

Windows (PowerShell):

claude mcp add --scope user ituran `
  --env ITURAN_USERNAME='[email protected]' `
  --env ITURAN_PASSWORD='your-password' `
  --env ITURAN_GLOBAL_BASE_URL=https://api-qa.ituran.com/api/v2 `
  -- npx -y ituran-mcp

The published launcher (start.js) auto-detects the system CA bundle on Linux (/etc/ssl/certs/ca-certificates.crt) and macOS (/etc/ssl/cert.pem) and sets NODE_EXTRA_CA_CERTS for you, so corp TLS to api-qa.ituran.com / api.ituran.com works out of the box. On Windows it leaves the env untouched — if upstream calls fail with UNABLE_TO_GET_ISSUER_CERT_LOCALLY, add --env NODE_EXTRA_CA_CERTS=C:\path\to\corp-ca-bundle.crt.

Switching to production

⚠️ The MCP has 24 mutating tools (create/update/delete — alerts, places, contacts, vehicle-groups, send-command, start-tracking, etc.). They register only with ITURAN_ALLOW_MUTATIONS=true; on prod, anything an LLM decides to call happens for real on the live fleet. Only flip when the work requires it.

Re-register with the prod URL:

claude mcp remove ituran -s user

claude mcp add --scope user ituran \
  --env ITURAN_USERNAME='[email protected]' \
  --env ITURAN_PASSWORD='your-password' \
  --env ITURAN_GLOBAL_BASE_URL=https://api.ituran.com/api/v2 \
  -- npx -y ituran-mcp

Start a new Claude Code session for the change to take effect.

Step 2 — Verify

claude mcp list

Expected: ituran: npx -y ituran-mcp - ✓ Connected.

Run this from any directory other than a clone of this repo. If your working directory contains a package.json named ituran-mcp (i.e., the source checkout), npm short-circuits to a local lookup and the bin won't resolve. From ~, /tmp, or any unrelated project — fine.

Step 3 — Use it

Tools usually load when the client session starts, so reconnect or start a new client session after changing configuration. In Claude Code, type /mcp to confirm the tools loaded (120 in the default read-only configuration), then try a call — e.g. "List my top 10 vehicles."

Tools

152 tool definitions across 22 families (151 register through the full-surface registrar with the degraded tool hidden, and 120 on the default read-only server: the 7-tool maintenance family is default-off, see ITURAN_ENABLE_MAINTENANCE). Full catalog with arguments and descriptions: TOOLS.md.

| Domain | Tools | File | |---|---:|---| | Vehicles | 8 | src/tools/vehicles.ts | | Alerts | 11 | src/tools/alerts.ts | | Events | 7 | src/tools/events.ts | | Places | 6 | src/tools/places.ts | | Contacts | 5 | src/tools/contacts.ts | | Drivers | 4 | src/tools/drivers.ts | | Commands | 5 | src/tools/commands.ts | | Diagnostics | 6 | src/tools/diagnostics.ts, src/tools/ev-overnight-charge-board.ts | | Vehicle groups | 6 | src/tools/vehicle-groups.ts | | Drive-permission groups | 4 | src/tools/drive-permission-groups.ts | | Exports | 2 | src/tools/exports.ts | | Info | 3 | src/tools/info.ts | | Users | 1 | src/tools/users.ts | | Trips | 10 | src/tools/trips.ts | | BI reports + composites | 17 | src/tools/reports.ts, src/tools/driver-timesheet-crosscheck.ts, src/tools/cost-center-usage-report.ts | | Operational reports | 19 | src/tools/reports-operational.ts, src/tools/saved-place-vehicle-overlap.ts, and dedicated report composites | | Safety / UBI | 13 | src/tools/safety.ts, src/tools/safety-hotspots.ts | | Maintenance (default-off — opt in via ITURAN_ENABLE_MAINTENANCE) | 7 | src/tools/maintenance.ts, src/tools/service-visit-report.ts, src/tools/inactivity-explanation-report.ts | | Advanced | 2 | src/tools/advanced.ts | | ITC temperatures | 5 | src/tools/itc.ts | | Fleet composites + resolver | 3 | src/tools/fleet.ts | | Named-group planner | 7 | src/tools/groups.ts | | Total registered with degraded tool hidden | 151 | |

Tool names follow ituran_<domain>_<verb>. Endpoint wrappers mirror upstream routes; composites and planner tools combine those routes into reusable fleet primitives.

Excluded by design: account/admin endpoints with no AI value (PUT /users/me/password, PUT /users/me/accept-terms, GET/PUT /app/usersettings, GET /internal/testip), and the entire identity-server-v1 surface (login flows, OTP, password-reset, onboarding, refresh-token admin) — those are either credential-handling anti-patterns or require a different auth model. The token manager calls POST /oauth/token internally; nothing else from identity-server-v1 is exposed.

How auth works

ITURAN_USERNAME + ITURAN_PASSWORD (env vars)
   ↓
token-manager → POST /api/v1/oauth/token (password grant) → access_token + refresh_token
   ↓
Global V2 tools ← Authorization: Bearer <access_token> (added per-request, internally)
  • First tool call (per process) is lazy: does a grant_type=password exchange against identity-server using the env-var creds.
  • Subsequent calls reuse the cached access_token until 30 s before expiry, then refresh in-place via grant_type=refresh_token (using the in-memory refresh_token that came back with the access_token).
  • Nothing on disk. Both tokens live only in the process's memory. When the MCP process exits (Claude Code session ends, machine reboots, etc.), they're gone — the next process starts fresh with another password grant. The password is read from env vars at startup; the LLM never sees any of these.
  • 2FA accounts are not supported — password grant returns an OTP challenge instead of tokens, and the MCP can't complete login without a human in the loop. Use a service account that doesn't require 2FA.

Configuration

| Var | Required | Default | Purpose | |---|---|---|---| | ITURAN_USERNAME | yes | — | Username for POST /oauth/token password grant | | ITURAN_PASSWORD | yes | — | Password for POST /oauth/token password grant | | ITURAN_APP_ID | no | unset | Optional integer included in the password-grant body | | ITURAN_GLOBAL_BASE_URL | no | https://api-qa.ituran.com/api/v2 | Override to prod (https://api.ituran.com/api/v2) for the live fleet | | ITURAN_IDENTITY_BASE_URL | no | derived from global URL | Override only if identity host diverges from global | | ITURAN_ALLOW_MUTATIONS | no | false | Gate for write tools. When unset/false the server is read-only — the 24 mutating tools (create/update/delete, send-command, start-tracking, share-drive) are not registered at all (no catalog weight, no dead-end calls). Set true to register and enable writes. | | ITURAN_ENABLE_MAINTENANCE | no | false | Opt-in for the default-off maintenance family (7 read tools). Maintenance data is per-customer — accounts that don't maintain it get empties or stale schedules read as "overdue service" — so unless enabled the module is invisible: no tools registered and zero mentions in prompts, instructions, or served resources (absence, never "disabled"). Naming maintenance in an explicit ITURAN_TOOL_FAMILIES list also enables it (the explicit list is authoritative). | | ITURAN_PLANNER_INLINE_THRESHOLD | no | 10 | Planner selects at/under this count inline operational summaries (0 disables). | | ITURAN_RADIUS_SELECTION_POLICY | no | allow | Coordinate-radius planner policy. allow keeps the generic selector available; saved-places-only rejects coordinate-radius selection and routes named-area workflows through ituran_places_list + ituran_select_vehicles_in_place. | | ITURAN_DRIVERS_CACHE_TTL_SECONDS | no | 300 | TTL for the driver-code→name registry cache behind ituran_safety_rank_drivers (0 disables). | | ITURAN_CONFIRM_DESTRUCTIVE | no | false | With mutations enabled: ask the user for a per-call confirmation (MCP elicitation) before any destructive tool (deletes, live device commands) executes. Fail-closed: when the connected client does not support elicitation, destructive calls are refused (destructive_confirmation_unavailable) instead of silently proceeding — use the host's own approval controls or unset the flag. | | ITURAN_MAX_RESULT_CHARS | no | 24000 | Size-guard ceiling (chars) for tool results — summarizers/trimming engage above it. Match it to your host's inline budget so the server's smart summaries run before the host's blunt head/tail slice (integer ≥ 2000). | | ITURAN_VERIFY_CREDENTIALS_AT_BOOT | no | true | Mint a token at startup: a wrong password / 2FA-gated account exits(1) with an authentication failed message before the transport connects (an attributable boot failure instead of dead tools mid-conversation). Transient identity trouble warns and continues. Costs one identity round-trip per process start; set false to restore the fully-lazy first mint. | | ITURAN_REQUEST_TIMEOUT_MS | no | 30000 | Per-request timeout. Stalled upstream calls abort with a TimeoutError instead of hanging the tool call. | | ITURAN_SOFT_DEADLINE_MS | no | 90000 | Wall-clock scheduling budget (ms) shared by every paced multi-request walk (chunk fan-outs, report page walks). When spent, no new upstream work is scheduled and the tool returns a partial, honestly-labelled result (coverage.complete:false / truncated) instead of dying at the host's MCP call deadline. | | ITURAN_MAX_RETRIES | no | 2 | Retries for transient failures (timeout / network / 5xx / 429) on read-only tools (including read-only POSTs like search/reports), with exponential backoff + jitter. Mutating tools are never auto-retried. | | NODE_EXTRA_CA_CERTS | no | unset | Linux: /etc/ssl/certs/ca-certificates.crt to trust corp TLS chain |

Catalog profiles. The default 120-tool read-only catalog costs ~172KB (~43.0k tokens) of model-facing definitions per conversation (127 tools / ~180KB / ~44.9k with ITURAN_ENABLE_MAINTENANCE=true); ITURAN_TOOL_FAMILIES shrinks it to what a deployment needs (measured with npm run measure:catalog):

| Profile | ITURAN_TOOL_FAMILIES | Tools | Model-facing catalog | |---|---|---:|---:| | Default (read-only) | (unset) | 120 | ~172KB (~43.0k tokens) | | Fleet ops | vehicles,trips,safety,fleet,groups,drivers | 44 | ~61KB (~15.3k tokens) | | Tracking lite | vehicles,fleet,groups | 17 | ~21KB (~5.3k tokens) | | Reports only | reports-bi,reports-operational,safety | 49 | ~86KB (~21.6k tokens) |

Deploying under small-model / security-first hosts

Hosts that target small or local models budget tool results and catalogs much tighter than a frontier-model client. The recommended deployment:

ITURAN_TOOL_FAMILIES=vehicles,fleet,trips,safety,groups,drivers   # 44 tools, ~15.3k catalog tokens
ITURAN_MAX_RESULT_CHARS=14000   # host offloads MCP results >15k chars; ~740 of those are its own
                                # untrusted-content wrapper — 14000 keeps results inline with the
                                # server's summaries + guidance markers intact. Small models: ~11000;
                                # nano: ~7000.
  • Entrypoint: always npx -y ituran-mcp (or node <path>/start.js) — never bare node <path>/dist/server.js. Only the launcher sets NODE_EXTRA_CA_CERTS before Node starts; behind a corp TLS chain the bare form fails every call with UNABLE_TO_GET_ISSUER_CERT_LOCALLY, which reads as a network outage.
  • Keep the boundary explicit: this package owns Ituran transport, credentials, upstream contracts, generic fleet primitives, and safety gates. Put host persona, user-facing style, approval UX, and product-specific workflow policy in a separate agent package or skill.
  • Read-only posture is model-legible: in read-only mode the tool descriptions, server instructions (front-loaded POSTURE), and the served tool-catalog resource all state that command/write verbs are unavailable — agents are told to say so plainly instead of constructing confirm-then-send flows.
  • Canonical schemas, forgiving adapters: tool schemas remain the published source of truth, while applicable calls accept common agent spellings (vehicle/plate, period, diagnostic, place, hours) before strict validation. Conflicting spellings fail loudly; unknown keys are never silently dropped.
  • Planner groups are not map areas: named vehicle groups are ephemeral internal selections, not saved places/geofences or map state. For a named-area request, call ituran_places_list with name_contains, resolve an exact place_id, then call ituran_select_vehicles_in_place. A zero match is terminal evidence for the current account; do not invent coordinates or substitute a radius-based group. Deployments that want this enforced at the server boundary can set ITURAN_RADIUS_SELECTION_POLICY=saved-places-only.
  • Fleet-wide saved-place history is one composite: call ituran_place_visitors once with place_name (or place_id) and the date window; use min_visit_minutes for “stayed over N minutes.” It resolves the saved place without guessing, scans heat maps with bounded concurrency, returns total/longest dwell metrics, and distinguishes retryable report failures from terminal account/data conditions. Use ituran_reports_heatmap only for one vehicle's episode details. vehicle_nickname is an operator-defined vehicle label that may look like a person's name—never present it as verified driver identity.
  • Fleet-wide all-place overlap is one composite: call ituran_saved_place_vehicle_overlap once with the requested account-local date. It freezes the full roster, exhausts every saved place, scans heat maps with bounded concurrency, and returns only places visited by at least two distinct normalized plates using exact saved radius or polygon geometry. Do not loop ituran_place_visitors or call discovery, place listing, trip search, or per-vehicle heat maps separately. Same-day co-visitation does not establish simultaneous presence or duplicate dispatch.
  • Private speed limits inside a saved site are one composite: call ituran_site_speeding once with place_name (or place_id), speed_limit_kmh, and the date window. It freezes the fleet roster, applies the saved place_id upstream, and independently verifies each returned fix against the exact saved radius or polygon; failed plates and incomplete report batches remain explicit.
  • Current return-to-base screening is one composite: call ituran_return_to_base_report once with the exact operator-approved saved-place names, local curfew, and freshness threshold. It freezes one fleet snapshot, applies exact saved radius or polygon boundaries, and returns counts plus a lossless semicolon-delimited outside/unlocated roster. Disclose every narrow-boundary warning and treat stale fixes as last-known evidence.
  • Current service-territory screening is one composite: call ituran_service_territory_report once with the operator-supplied center, radius, and freshness threshold. It freezes one fleet snapshot and returns exact inside/outside/unlocated counts plus a lossless farthest-first outside roster. A stale fix is last-known evidence, not proof of unauthorized use.
  • Current area occupancy has an aggregate: ituran_places_stats returns occupancy.occupied_places and occupancy.unique_vehicles_in_places as the direct “how many vehicles are inside how many areas” answer. total_place_memberships can exceed the unique-vehicle count because saved places overlap; places carries the per-place ranking.
  • Saved-place geometry quality is one composite: call ituran_places_stats with view:"registry_audit" and the operator's small-radius, large-radius, and near-center thresholds. It exhausts the registry internally, reports exact geometry/radius partitions, and returns near-center pairs in compact lossless pages; polygon bounding discs are explicitly marked as approximations.
  • Stale open-event debt is audited before response bounding: call ituran_events_stats with board:"stale_open_states" and older_than_days. It drills every positive definition internally, returns only definition-level stale counts and oldest ages, and keeps failed reads, count drift, malformed times, future times, and duplicate vehicle states explicit in coverage. An old open state is possible closure or data-maintenance debt, not proof of a current incident.
  • Current fleet group coverage is one exact set audit: call ituran_vehicle_groups_list with view:"coverage_audit". It freezes the complete roster, walks every nested group membership, and returns exact ungrouped current plates separately from stale registry plates and current plates assigned to multiple groups. Both the fleet and registry partitions must reconcile before coverage.complete is true.
  • Fleet reporting latency is one fresh SLA view: call ituran_fleet_summary with view:"reporting_latency". It uses the full frozen roster as the share denominator, measures last-location timestamps against account-local now, and returns cumulative one-hour/day shares plus nearest-rank P50/P90 ages. Missing, epoch-artifact, invalid, and future timestamps remain explicit, and coverage must reconcile before the board is treated as complete.
  • High-mileage meter divergence is one current composite: call ituran_fleet_activity_report with view:"meter_divergence" and omit top_n/material_gap_pct unless the user supplied them. It selects the default top ten device odometers, joins GPS virtual odometers once, ranks every comparison in compact CSV, and surfaces the default 20% review set with timestamps, reliability, and exact coverage. Different meter sources can diverge after resets, replacements, or telemetry gaps; a flag is not evidence of fraud.
  • Insurance-renewal evidence uses one consistent trip population: call ituran_trips_search with view:"insurance_renewal" and exact dates. The composite exhausts trips once for distance, night share, nearest-rank speed percentiles, and driver identification, while fetching the fleet safety aggregate concurrently. Inspect coverage.missing_periods and coverage.partial_sources; safety enrollment coverage remains unknown even when its aggregate succeeds. The pack informs a renewal discussion and is not an underwriting decision.
  • Circular congestion exposure is one endpoint screen: call ituran_trips_search with view:"congestion_exposure", the operator's center/radius, charge windows, and exact dates. It counts trips once across start-only, end-only, and both-endpoint partitions, returns charged and all-hours exposure, and reconciles the full end-owned trip feed through the next-day lookahead. Invalid endpoint points make coverage partial. A circle is not the legal-zone polygon, and trips that only cross it are missed, so the estimate can under-count.
  • Driver-day payroll cross-checks are one BI composite: call ituran_reports_bi_driver_timesheet_crosscheck with the requested window. It exhausts the daily-driver report, returns every activity-span versus reported-driving comparison in compact CSV, and flags impossible duration-above-span rows with exact coverage. A BI entitlement denial is a successful typed unknown and stops immediately; raw trip pages are not a substitute. The result supports a wage conversation, never a certified attendance claim.
  • Rendering is a host capability: the MCP returns fleet data, coordinates, and time series. Agents should render a chart or map only when their host supports it; otherwise return a compact table and never claim a read-only call changed UI selection state.
  • Planner rows are data-minimized: inline selections and ituran_group_get return operational vehicle summaries without contact details, VINs, device/network identifiers, or internal IDs. Use the driver tools only when the user explicitly requests contact details.
  • Elicitation: ITURAN_CONFIRM_DESTRUCTIVE requires a client that supports MCP elicitation; on clients without it, destructive calls are refused, not silently run — rely on the host's own approval controls if you enable mutations.
  • Parallel tool calls are safe: the server is stateless per call and its token cache is mutex-guarded with a generation-guarded invalidate (a lagging 401 can't discard a freshly minted token). Hosts that serialize stdio servers can safely enable per-server parallelism.
  • Ask the server what it can do: the ituran://reference/capabilities resource states this deployment's posture (read-only vs mutations), the active environment (production vs QA host), unavailable verbs, and any family filters — agent-readable, byte-stable per deployment.

Safety & resilience. The server starts read-only — write tools are registered only when ITURAN_ALLOW_MUTATIONS=true; on prod it prints a loud banner and reports the mutation state at startup. Every tool accepts an optional format argument ("json" default, or "text" for a compact markdown rendering), and large list responses are size-capped to stay under a context budget (trimmed to valid JSON with a _truncated marker). Tools carry MCP readOnlyHint / destructiveHint / idempotentHint annotations, and thrown errors surface as structured JSON envelopes ({error, status?, error_code?, message}) with remedy hints intact. On a 401 the token is refreshed and the request retried once.

Rotating creds

Tokens never persist, so there's no on-disk state to clean up. To swap accounts:

  1. Update ITURAN_USERNAME / ITURAN_PASSWORD in your MCP client configuration.
  2. Restart or reconnect the MCP process.

Upgrading from 1.0.0 → 1.1.0+? The old version cached a refresh token at ~/.ituran-mcp/state.json. Since 1.1.0 nothing reads or writes there, but the file is left in place by the upgrade. Run rm -rf ~/.ituran-mcp/ once after upgrading to remove the orphan.

Local development (contributors)

Clone the repo, build, and run from source:

git clone https://github.com/ituranlabs/ituran-mcp.git
cd ituran-mcp
npm install
npm run build
ITURAN_USERNAME=... ITURAN_PASSWORD=... node start.js

The server reads JSON-RPC on stdin and writes responses on stdout. There are no HTTP endpoints — the MCP client launches the binary and talks over the inherited pipes. start.js is a cross-platform launcher (Linux / macOS / Windows) that auto-detects the system CA bundle on Linux and macOS so corp TLS works without extra config.

To register your local checkout instead of the published package:

claude mcp add --scope user ituran-local \
  --env ITURAN_USERNAME=... --env ITURAN_PASSWORD=... \
  -- node /absolute/path/to/ituran-mcp/start.js

Smoke test (no upstream call — just exercises the JSON-RPC plumbing):

( printf '%s\n%s\n%s\n' \
    '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"1"}}}' \
    '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' \
    '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
  | ITURAN_USERNAME=fake ITURAN_PASSWORD=fake node dist/server.js 2>/dev/null \
) | head -2

Publishing a new version (maintainers)

Published to the public npm registry under the unscoped name ituran-mcp.

# one-time: log in to the public npm registry (needs an npmjs.com account with publish rights)
npm login

# bump version, then publish — `prepublishOnly` runs the build for you
npm version patch    # or minor / major
npm publish          # public by default (unscoped name)
git push --follow-tags

npm publish only ships the files listed in "files" in package.json (currently dist/, start.js, README.md, TOOLS.md, LICENSE). Source TypeScript and node_modules are not published. Run npm publish --dry-run first to inspect the exact tarball contents.

License

MIT — see LICENSE.