owntracks-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@owntracks-mcpWhere am I right now?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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:
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, …).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 AgentTools
Tool (in Hermes: | Purpose |
| Latest position: address, regions, age, accuracy, speed, battery, map link. No |
| History for a time range: distance travelled, top speed, stays (where and how long) and a thinned-out route. |
| Straight-line distance from the latest position to a point, or to |
| All users and devices. |
| Address from the Recorder's geocache. |
| 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, ordocker 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: 60If 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-mcpPut 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/skills3. Test
hermes mcp test owntracks # should report 6 tools
hermes chat
> Where am I right now?Configuration (environment variables)
Variable | Required | Meaning |
| yes | Base URL of the Recorder, e.g. |
| no | HTTP basic auth, if a reverse proxy (nginx, Caddy, Traefik) sits in front |
| no |
|
| no | e.g. |
| no | Who "I" / |
| no | Default device of that user |
| no |
|
| 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 8765mcp_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/pytestThe 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 toolsget_distanceBRead-onlyIdempotent
Straight-line distance from the latest position(s) to a point (or to the configured home).
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Target latitude. Omit both to use home. | |
| lon | No | Target longitude. Omit both to use home. | |
| user | No | OwnTracks user name. "me" = configured default user. Omit for everyone (where supported). | |
| device | No | Device name of that user. Omit if the user has only one device. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_locationARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| user | No | OwnTracks user name. "me" = configured default user. Omit for everyone (where supported). | |
| device | No | Device name of that user. Omit if the user has only one device. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_historyARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | End of range, same formats as start. A plain date means end of that day. Default: now. | |
| user | No | OwnTracks user name. "me" = configured default user. Omit for everyone (where supported). | |
| start | No | Start 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. | |
| device | No | Device name of that user. Omit if the user has only one device. | |
| max_points | No | Max track points to return (thinned evenly). | |
| stay_min_minutes | No | Minimum time at one place to count as a stay. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_devicesARead-onlyIdempotent
List all OwnTracks users and their devices known to the Recorder.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_statusARead-onlyIdempotent
Check the connection to the OwnTracks Recorder and show the active configuration (no secrets).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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_geocodeARead-onlyIdempotent
Look up an address for coordinates in the Recorder's geocache (only already-seen places).
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
6 tool updates
v0.1.0- First observed
get_distance - First observed
get_last_location - First observed
get_location_history - First observed
list_devices - First observed
owntracks_status - First observed
reverse_geocode
TDQS
Scored across 6 tools
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.
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.
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.
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
Related MCP Connectors
Geolocate Me turns your phone into location context for any AI assistant. Install the iOS or Android app, connect once with OAuth, and your GPS is queryable in natural language. Ask where you are, where you parked, where you were yesterday at 3pm, or how long you were at the office — the assistant calls the tool and answers with a real street address. https://geolocateme.app
Read-only MCP server: let AI agents read your ORANO saved-video library, tasks, and memory.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for the loc8n Geographic Data API. Exposes U.S. demographics, housing, mortgage, migration, employment, and geographic data as tools.2351 npmMIT
- FlicenseNot gradedqualityBmaintenanceEnables read-only querying of a local SQLite database via MCP, with tools to list tables, retrieve schema, and execute SELECT/WITH/EXPLAIN queries.-
- AlicenseAqualityCmaintenanceA private location archive with an MCP server, letting an agent answer questions about your past stays, trips, cities, and travel stats from data in your own Postgres.14MIT
- AlicenseNot gradedqualityAmaintenanceMCP 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.1MIT