Skip to main content
Glama
de-niji

owntracks-mcp

by de-niji

OwnTracks for Hermes Agent

Connects OwnTracks to Hermes Agent (Nous Research), so Hermes can answer questions like:

  • "Where am I right now?" / "Where is Anna?"

  • "Where was I yesterday afternoon?" / "When did I get to the office today?"

  • "How far is Anna from home?"

  • "How many kilometres did I drive this week?"

The project has two parts:

  1. owntracks-mcp: an MCP server (Python) that queries the REST API of the OwnTracks Recorder. It works with Hermes and with any other MCP client (Claude Desktop, Cursor, …).

  2. skills/owntracks/SKILL.md: a Hermes skill that tells the agent when and how to use the tools (always state how old a position is, summarise stays, respect privacy).

All access is read-only. The Recorder's delete endpoint (/api/0/kill) is never called.

OwnTracks app ──MQTT/HTTP──▶ OwnTracks Recorder ◀──HTTP── owntracks-mcp ◀──MCP (stdio)── Hermes Agent

Tools

Tool (in Hermes: mcp_owntracks_…)

Purpose

get_last_location(user?, device?)

Latest position: address, regions, age, accuracy, speed, battery, map link. No user → everyone. user="me" → default user.

get_location_history(user, device?, start?, end?, max_points?, stay_min_minutes?)

History for a time range: distance travelled, top speed, stays (where and how long) and a thinned-out route.

get_distance(lat?, lon?, user?, device?)

Straight-line distance from the latest position to a point, or to OWNTRACKS_HOME when no coordinates are given.

list_devices()

All users and devices.

reverse_geocode(lat, lon)

Address from the Recorder's geocache.

owntracks_status()

Connection check and active configuration (no secrets).

Time arguments accept now, today, yesterday, relative values like 30m, 6h, 2d, 1w, as well as 2026-09-27 or 2026-09-27T14:30 (local time zone).

Related MCP server: sqlite-mcp-local

Requirements

  • A running OwnTracks Recorder that the machine running Hermes can reach over HTTP (default port 8083). If you don't have one yet, owntracks/quicksetup is the quickest route, or docker run -p 8083:8083 owntracks/recorder.

  • Python ≥ 3.10, ideally with uv.

Installing in Hermes

1. Register the MCP server

In ~/.hermes/config.yaml (full example: examples/hermes-config.yaml):

mcp_servers:
  owntracks:                 # keep this name, the skill expects mcp_owntracks_* tools
    command: uvx
    args: ["--from", "git+https://github.com/de-niji/OwnTracksHermes", "owntracks-mcp"]
    env:
      OWNTRACKS_URL: "http://localhost:8083"
      OWNTRACKS_TIMEZONE: "Europe/Berlin"
      OWNTRACKS_DEFAULT_USER: "alice"
      OWNTRACKS_DEFAULT_DEVICE: "phone"
      OWNTRACKS_HOME: "51.9607,7.6261"
    timeout: 60

If the GitHub repository is private, or you prefer a local install:

git clone https://github.com/de-niji/OwnTracksHermes ~/OwnTracksHermes
cd ~/OwnTracksHermes && uv venv && uv pip install .
# then in config.yaml:  command: /home/<you>/OwnTracksHermes/.venv/bin/owntracks-mcp

Put passwords in ~/.hermes/.env and reference them in the config as ${OWNTRACKS_PASSWORD}.

2. Install the skill

Either of these works:

# a) copy it
cp -r skills/owntracks ~/.hermes/skills/

# b) or load it straight from the cloned repo, in ~/.hermes/config.yaml:
# skills:
#   external_dirs:
#     - /home/<you>/OwnTracksHermes/skills

3. Test

hermes mcp test owntracks      # should report 6 tools
hermes chat
> Where am I right now?

Configuration (environment variables)

Variable

Required

Meaning

OWNTRACKS_URL

yes

Base URL of the Recorder, e.g. http://localhost:8083 or https://example.com/owntracks (without /api/0)

OWNTRACKS_USERNAME / OWNTRACKS_PASSWORD

no

HTTP basic auth, if a reverse proxy (nginx, Caddy, Traefik) sits in front

OWNTRACKS_VERIFY_SSL

no

true (default), false, or the path to a CA bundle

OWNTRACKS_TIMEZONE

no

e.g. Europe/Berlin. Defaults to the system time zone

OWNTRACKS_DEFAULT_USER

no

Who "I" / me is

OWNTRACKS_DEFAULT_DEVICE

no

Default device of that user

OWNTRACKS_HOME

no

lat,lon of home, for "how far from home"

OWNTRACKS_TIMEOUT

no

HTTP timeout in seconds (default 15)

Addresses only appear if the Recorder does reverse geocoding (OTR_GEOKEY). Named places like "Home" or "Work" come from the regions (waypoints) set up in the OwnTracks app.

Security

The OwnTracks Recorder has no authentication of its own. Anyone who can reach its API can read, and even delete, all data. So:

  • Keep the Recorder reachable only locally or over a VPN, or put a reverse proxy with basic auth in front of it (and use OWNTRACKS_USERNAME / OWNTRACKS_PASSWORD).

  • This MCP server only exposes read-only tools, marks them with readOnlyHint, and never calls the delete endpoint.

  • Location data is very personal. The skill instructs Hermes to share it only with the person asking.

Running as an HTTP server (optional)

If Hermes runs on a different machine than the Recorder:

owntracks-mcp --transport streamable-http --host 0.0.0.0 --port 8765
mcp_servers:
  owntracks:
    url: "http://recorder-host:8765/mcp"

Don't expose this port to the internet unprotected.

Development

uv venv && uv pip install -e ".[dev]"
.venv/bin/pytest

The tests run against a simulated Recorder (tests/fake_recorder.py). One of them launches the real server over stdio, the way Hermes does. Tested with MCP Python SDK 1.x and 2.x.

License

MIT

Available Tools

6 tools
get_distanceB
Read-onlyIdempotent

Straight-line distance from the latest position(s) to a point (or to the configured home).

ParametersJSON Schema
NameRequiredDescriptionDefault
latNoTarget latitude. Omit both to use home.
lonNoTarget longitude. Omit both to use home.
userNoOwnTracks user name. "me" = configured default user. Omit for everyone (where supported).
deviceNoDevice name of that user. Omit if the user has only one device.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint=false, and idempotentHint, covering safety. The description adds that the distance is straight-line (not route) and based on latest position(s), which is useful behavioral context but still leaves return format, error behavior, and multi-device semantics unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that states exactly what the tool does with no filler. Every phrase contributes to understanding the operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a full output schema and annotations covering safety, the description needs only to convey the core concept. It does so adequately for a read-only computation, though it could briefly clarify how multiple latest positions are combined.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so each parameter (lat, lon, user, device) is fully documented in the schema. The description adds no parameter-specific syntax or meaning beyond what the schema already provides, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific operation: compute straight-line distance from latest positions to a target point or home. The resource and calculation type are clear, but the description does not explicitly differentiate it from siblings like get_last_location or get_location_history.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives, nor any prerequisites or exclusions. The phrase 'or to the configured home' implies one usage mode but does not route the agent among the sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_last_locationA
Read-onlyIdempotent

Current (most recent) position of a user/device, or of everyone if no user is given.

Returns coordinates, time and age of the fix, address (if the Recorder geocodes), regions the device is in, accuracy, speed, battery and a map link. Always mention how old the position is.

ParametersJSON Schema
NameRequiredDescriptionDefault
userNoOwnTracks user name. "me" = configured default user. Omit for everyone (where supported).
deviceNoDevice name of that user. Omit if the user has only one device.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-open-world, so safety is covered. The description adds a conditional behavior ('address if the Recorder geocodes') and a presentation requirement ('always mention how old the position is'), but the rest of the return list is behavioral filler given an output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then output summary and one actionable instruction. It is short and earns most of its space, though the output enumeration is partially redundant with the output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-param read tool with full schema coverage, annotations, and an output schema, the description supplies everything needed to call it correctly, plus a presentation hint. Only the lack of sibling routing keeps it from being fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented, including the 'me'/omit semantics. The description's 'or of everyone if no user is given' duplicates schema text rather than adding syntax or format detail, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Current (most recent) position of a user/device') and adds the scope behavior when no user is supplied. The word 'current/most recent' implicitly separates it from get_location_history, so an agent can distinguish it from its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'or of everyone if no user is given' clause gives a usage condition, but it largely restates the schema default. No sibling tool (get_location_history, owntracks_status, reverse_geocode) is named as an alternative, so the when-to-use routing is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_location_historyA
Read-onlyIdempotent

Route/track of a device in a time range, with distance travelled and places where it stayed.

Use the 'stays' list to answer "where was X" questions and 'points' for the route. Times are in the configured local time zone.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNoEnd of range, same formats as start. A plain date means end of that day. Default: now.
userNoOwnTracks user name. "me" = configured default user. Omit for everyone (where supported).
startNoStart of range: 'today', 'yesterday', relative like '6h'/'2d'/'1w' (ago), a date '2026-09-27' or ISO time '2026-09-27T08:00'. Default: 24h ago.
deviceNoDevice name of that user. Omit if the user has only one device.
max_pointsNoMax track points to return (thinned evenly).
stay_min_minutesNoMinimum time at one place to count as a stay.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly, idempotent, and non-open-world behavior, so the safety profile is covered. The description still adds genuine context the annotations lack: results are expressed in the configured local time zone and the payload separates stays from raw points. It does not mention auth or rate limits, but this is a read tool where that gap is minor.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the resource definition and followed by output-usage and time-zone notes; nothing is wasted. The clipped opening fragment ('Route/track of a device...') is slightly terse but still readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a full output schema and rich annotations, the description only needs to add orientation, and it does: what the payload contains, how to use each list, and the time-zone convention. It is essentially complete, lacking only sibling-routing context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all six parameters (start, end, user, device, max_points, stay_min_minutes) are already documented with formats, defaults, and bounds in the schema. The description adds nothing parameter-specific, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource and scope: the route/track of a device over a time range, plus distance travelled and stays. That is far more informative than the bare tool name, though it does not explicitly contrast itself with siblings like get_last_location or get_distance, which an agent must infer.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives real guidance on how to consume the result ('stays' for where-was-X questions, 'points' for the route), which is useful routing advice. However, it says nothing about when to choose this tool over get_last_location, get_distance, or owntracks_status, and lists no preconditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_devicesA
Read-onlyIdempotent

List all OwnTracks users and their devices known to the Recorder.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and openWorldHint=false, so the safety profile is covered. The description adds the useful scoping fact that results are limited to devices 'known to the Recorder,' but says nothing about pagination, ordering, or result size.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; every word contributes to identifying the resource and its scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not needed, and the tool is a simple no-argument read. The one remaining gap is routing guidance versus sibling tools, which is not strictly required for correct invocation but would help selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the rubric the baseline is 4; there is nothing for the description to document, and it correctly avoids inventing parameter details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('List') and a clear resource ('OwnTracks users and their devices'), and the 'known to the Recorder' qualifier scopes the result set. It is distinguishable from siblings like get_last_location or get_location_history, though it does not explicitly name what distinguishes it from owntracks_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the tool for enumerating devices, but there is no explicit when-to-use statement, no reference to alternative siblings, and no note about prerequisites or empty results.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

owntracks_statusA
Read-onlyIdempotent

Check the connection to the OwnTracks Recorder and show the active configuration (no secrets).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint=false, so the safety profile is covered. The description's only added behavioral detail is '(no secrets)', which usefully tells the agent the configuration output is safe to surface, but it omits failure/error semantics and response shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the primary action and appends the configuration detail with no waste. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be described, annotations cover the safety profile, and there are no parameters. The only mild gap is what a 'connection check' failure communicates, but that is reasonably delegated to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, which is the baseline-4 case. There is nothing for the description to clarify, and the 100% schema coverage confirms no semantic gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Check the connection') and resource ('OwnTracks Recorder') plus a secondary action of showing active configuration. It is clearly distinct from the location-oriented siblings (list_devices, get_last_location, etc.), though it doesn't explicitly name them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The diagnostic framing implies this is used to verify recorder connectivity or inspect current configuration, but there is no explicit when-to-use guidance, no prerequisites, and no reference to alternatives. Usage is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reverse_geocodeA
Read-onlyIdempotent

Look up an address for coordinates in the Recorder's geocache (only already-seen places).

ParametersJSON Schema
NameRequiredDescriptionDefault
latYes
lonYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnlyHint, idempotentHint, openWorldHint=false), so the extra bar is lower. The description adds genuinely useful context beyond them: the lookup is scoped to a local geocache of previously seen places, which signals that unknown coordinates may yield no result. It does not say what happens on a cache miss (empty result vs error).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with the operation front-loaded and the critical scope constraint parenthetically attached; every clause earns its place and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value documentation is not required, and annotations cover the safety profile. The remaining gap is the cache-miss behavior, which the description hints at ('only already-seen places') but never resolves.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden, and it largely does not: it only implies the two numbers are coordinates. Units, precision, and coordinate ordering are left entirely to the agent's prior knowledge, though the -90/90 and -180/180 bounds in the schema mitigate this somewhat.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Look up an address for coordinates') and adds a scope qualifier ('in the Recorder's geocache (only already-seen places)') that makes it functionally distinct from the sibling location tools. It does not explicitly name a sibling it is confused with, so it falls short of the 5 bar.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Only already-seen places' implies a usage boundary (it will not resolve arbitrary coordinates), but the description never states when to reach for this versus the other location tools, nor what to do when the coordinate is not cached. Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv0.1.0
    • First observedget_distance
    • First observedget_last_location
    • First observedget_location_history
    • First observedlist_devices
    • First observedowntracks_status
    • First observedreverse_geocode

TDQS

A3.8/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: connectivity/config, device listing, current location, distance calculation, historical route, and reverse geocoding. There is no meaningful overlap between any pair of tools.

Naming Consistency4/5

Five of six tools follow a consistent verb_noun pattern (list_devices, get_last_location, get_distance, get_location_history, reverse_geocode). The odd one out, owntracks_status, breaks the pattern but remains unambiguous.

Tool Count5/5

Six tools is well-scoped for a read-only location tracking server. Each tool earns its place and the set is neither thin nor bloated.

Completeness4/5

The core read operations are covered: status, device listing, current location, history, distance, and reverse geocoding. Minor gaps exist—reverse_geocode only works with cached places, and there is no tool for arbitrary geocoding or device management—but these may be outside the server's intended scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables read-only querying of a local SQLite database via MCP, with tools to list tables, retrieve schema, and execute SELECT/WITH/EXPLAIN queries.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for Home Assistant that lets you control and query your smart home through natural language via MCP clients. Provides tools for entities, devices, services, automations, scripts, history, add-ons, and system info, with read-only access by default and optional configurable write support.
    1
    MIT