MCP Function: how can the documentation can found?

Tronio 7 months ago

on thing I forgot to add for the suggestions
5. now when I ask the location of a device it just returns with the coordinates, would be more helpful to get the geocoded address

although I see that the model can't see the geocoded address and just the coordinates but would be nice, or idk if its possible to get it working like that in mcp but if a user asks for a location then give it in google maps link always?

Anton Tananaev 7 months ago

It should do geocoding automatically.

Anton Tananaev 7 months ago

Tronio those are some good suggestions, thanks.

Simo 6 months ago

Do you know how to make it work for traccar v6.12.0 (last release)?

There is a change:

openid.clients config
List of OpenID Connect clients for the built-in provider. Value should be a comma-separated list of 'clientId:clientSecret:redirectUri' entries. Multiple redirect URIs can be specified using '|' as a separator.

I'm trying something like this but without success --> HTTP 400 Bad Request:

<entry key='web.url'>https://traccar.mysite.com</entry>
<entry key='openid.clients'>chatgpt-traccar-mcp:secret_to_generate:https://traccar.mysite.com/api/mcp</entry>
<entry key='web.mcp.enable'>true</entry>

Any help would be appreciated

Anton Tananaev 6 months ago

Are you sure the value are correct?

Simo 6 months ago

Ok! I solved it in this way:

<entry key='openid.clients'>chatgpt-traccar-mcp:secret_to_generate:https://chatgpt.com/connector_platform_oauth_redirect</entry>

Remember to login to your traccar server before adding the connector to chatgpt

shanelord 14 days ago

Getting Claude (claude.ai) working with Traccar's MCP server. This builds on the earlier ChatGPT + Traccar MCP posts above - same underlying Traccar feature, but Claude's OAuth client behaves a little differently, and there were two real bugs to work around. Posting the full setup and fixes here in case it saves someone else the same afternoon.

1. Base Traccar config

In traccar.xml:

<entry key='web.url'>https://your-domain.com</entry>
<entry key='web.mcp.enable'>true</entry>
<entry key='openid.clients'>claude-mcp:YOUR_GENERATED_SECRET:https://claude.ai/api/mcp/auth_callback</entry>

Generate the secret with:

openssl rand -hex 32

Important: the openid.clients format needs THREE colon-separated fields, not two. Traccar parses each entry as clientId:secret:redirectUris (OidcResource.java, getClients()):

String[] values = entry.split(":", 3);
clients.put(values[0], new ClientConfig(values[1], Arrays.stream(values[2].split("\\|"))
        .map(URI::create)
        .collect(Collectors.toSet())));

If you only give it clientId:secret (as older posts describe for other MCP clients), you'll get an ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2 when anything hits /api/oidc/authorize. The third field is the exact redirect URI the client will use, for Claude that's:

https://claude.ai/api/mcp/auth_callback

(You can pipe-separate | multiple redirect URIs if you need more than one client/callback.)

This is actually documented in Traccar's own config reference (openid.clients: "comma-separated list of 'clientId:clientSecret:redirectUri' entries, multiple redirect URIs can be specified using '|' as a separator"), easy to miss if you're going off an older forum post that only showed two fields.

Restart Traccar after editing.

If you get HTTP 400 Bad Request instead

That means Traccar did parse your 3-field entry fine, but the redirect_uri the OAuth client actually sent doesn't match any URI you registered. From the source:

URI target = URI.create(redirectUri);
if (!client.redirectUris().contains(target)) {
    throw new WebApplicationException(Response.Status.BAD_REQUEST);
}

The redirect URI has to match exactly, and it's different per client:

  • ChatGPT: https://chatgpt.com/connector_platform_oauth_redirect
  • Claude: https://claude.ai/api/mcp/auth_callback

If you're setting this up for a different client, check what redirect URI it actually sends (you can see it in the URL query string during the failed authorize attempt) rather than guessing.

2. Add the connector in Claude

In claude.ai: Settings, then Connectors, then Add, then Add custom connector.

  • Remote MCP server URL: https://your-domain.com/api/mcp
  • OAuth Client ID: claude-mcp
  • OAuth Client Secret: the secret you generated above

You do not get an Authorization URL / Token URL field to fill in manually, Claude discovers those itself from Traccar's OAuth metadata (/.well-known/oauth-authorization-server). This is where the second issue comes in.

3. If you get a blank page when authorizing

If clicking "Connect" sends your browser to a URL like:

https://your-domain.com/authorize?response_type=code&client_id=claude-mcp&...

(no /api/oidc/ in the path) and the page is just blank, that's the bug. Traccar's real OAuth endpoints live at /api/oidc/authorize and /api/oidc/token, but Traccar only publishes its discovery document at the plain root:

https://your-domain.com/.well-known/oauth-authorization-server

For an issuer with a path component (Traccar's issuer is https://your-domain.com/api/oidc), RFC 8414 says spec-compliant clients should look for that metadata at:

https://your-domain.com/.well-known/oauth-authorization-server/api/oidc

That path 404s on Traccar, so Claude's client can't find the real metadata and falls back to guessing {your-domain}/authorize and {your-domain}/token, both wrong. You can confirm this is what's happening by checking what Traccar actually serves:

curl https://your-domain.com/.well-known/oauth-authorization-server

It'll return valid JSON with the correct authorization_endpoint and token_endpoint, Claude just never looks there for a path-based issuer.

This isn't something you can fix in Traccar's config. It needs either a Traccar-side fix (publish metadata at the RFC-compliant path too) or a client-side fix (Anthropic/Claude respecting the discovered authorization_endpoint/token_endpoint instead of guessing). Worth a bug report either direction, but in the meantime the workaround is a reverse-proxy rewrite rule: rewrite requests where the path is exactly /authorize or /token (on your Traccar domain) to /api/oidc/authorize / /api/oidc/token respectively, leaving everything else untouched.

How you do this depends on your proxy:

  • Plain Traefik, add a middleware + router:
    http:
      middlewares:
        traccar-oidc-rewrite:
          replacePathRegex:
            regex: "^/(authorize|token)$"
            replacement: "/api/oidc/$1"
      routers:
        traccar-oidc-fix:
          rule: "Host(`your-domain.com`) && (Path(`/authorize`) || Path(`/token`))"
          service: your-traccar-service
          middlewares: [traccar-oidc-rewrite]
          priority: 300
    
    (priority must beat any catch-all router for the same host)
  • nginx: add exact-match location blocks for /authorize and /token that internally rewrite the request path to add the /api/oidc prefix before proxying to your Traccar backend, placed before your general reverse proxy block.
  • Caddy: use a handle block for /authorize (and separately /token) that rewrites the URI to prepend /api/oidc, placed before your general reverse_proxy directive.
  • Pangolin (Traefik-based): same idea, but be aware Pangolin's own generated routers and any "middleware manager" add-ons may already have a higher-priority catch-all router for your host. Check via the Traefik API (/api/http/routers) that your rewrite router actually wins, not just that you added it.

The regex only matches the bare /authorize and /token paths exactly, so it's inert for everything else Traccar serves.

4. If you have country/IP allow-listing on your reverse proxy

Worth flagging since it cost me a while to diagnose: Claude's OAuth token exchange and MCP tool calls happen server-to-server from Anthropic's own infrastructure (US-based), not from your browser. If your proxy has a geo-block or IP allowlist (e.g. "only allow my own country," common if you've locked down remote access), Claude's requests will get blocked. Usually the interactive authorize step still works fine because it's your own browser doing it, but the token exchange (headless, from Claude's servers) silently fails with something like "authorization failed" or a token-exchange error, often after a slow hang rather than an instant rejection.

Fix: add an explicit, higher-priority bypass rule for the OAuth/MCP paths specifically, before your country/IP block:

  • Bypass for path /api/oidc/*
  • Bypass for path /api/mcp
  • (keep your existing block for everything else)

Those two path prefixes are already protected by the OAuth client secret and your own Traccar login, so exempting them from IP/geo restrictions doesn't meaningfully weaken security. The rest of your site stays locked down.

shanelord 14 days ago

One more gotcha, plus the summary checklist for the whole setup:

5. Gotcha while testing: service workers

If you're testing the flow in a browser tab where you'd previously loaded the Traccar web app, and you're still seeing a blank page or stale behavior after fixing the above, Traccar's frontend is a PWA and registers a service worker. It can serve a cached app shell for the /authorize navigation instead of hitting your fixed backend. Clear it via DevTools, Application, Service Workers, Unregister (and clear the workbox-precache cache), or just test in an incognito window.

Summary checklist

  • openid.clients has 3 fields: clientId:secret:redirectUri
  • web.mcp.enable is true
  • Redirect URI matches exactly what Claude sends (https://claude.ai/api/mcp/auth_callback)
  • Reverse proxy rewrites bare /authorize and /token to /api/oidc/authorize / /api/oidc/token
  • Any geo/IP restrictions exempt /api/mcp and /api/oidc/*
  • Logged into Traccar in the same browser you use to click "Connect"
  • Test in incognito if you hit stale/blank-page behavior

Once all of that's in place, Claude can call the two currently-available tools (device-position by numeric device ID, and traccar-version). Note it's by internal numeric deviceId, not the device's identifier/IMEI string shown in the UI, worth checking Device, Attributes if you're not sure which is which.

Anton Tananaev 14 days ago

I think the right solution is to update Traccar code to avoid all this complexity.

shanelord 14 days ago

@anton Agreed - there are improvements that the team could make to simplify this dramatically.

  1. Fix the RFC 8414 discovery (highest impact)
    This is the root cause of blank-page issues when trying to authenticate. Traccar's OIDC issuer is https://domain/api/oidc (has a path component), but the discovery document is only served at the bare root /.well-known/oauth-authorization-server. Spec-compliant clients look for it at /.well-known/oauth-authorization-server/api/oidc per RFC 8414, get a 404, and fall back to guessing wrong endpoints. Publishing the metadata at the correct path (in addition to the root, for backward compat) would fix this for every client, not just Claude, with zero reverse-proxy workarounds needed.

  2. Validate openid.clients and fail loudly, not with a stack trace
    Feeding it the 2-field format (which is what the original forum guidance showed) throws a raw ArrayIndexOutOfBoundsException straight into the HTTP response. Same for a redirect_uri mismatch, bare 400 with no body. A startup-time validator ("openid.clients entry must be clientId:secret:redirectUri") and a proper OAuth-style error body ({"error": "invalid_request", "error_description": "..."}) would turn a multi-hour debugging session into a five-second fix for the next person.

  3. Manage OAuth clients from the admin UI, not XML
    Every other credential in Traccar (users, devices, notifications) has a UI. OAuth clients are XML-file-only, which is exactly the kind of thing that invites typos in the 3-field format. A simple settings panel (generate client ID/secret, paste redirect URI, done) would remove most of the friction I hit.

  4. Handle the unauthenticated-authorize case gracefully
    Right now, hitting /authorize while logged out just 401s. Standard OAuth UX is to redirect to login and resume the flow afterward. This was already flagged in the forum thread and is a setup friction issue.

  5. Expand the MCP tool set
    Also flagged in the forum thread months ago and still true: no device lookup by name (numeric ID only), no historical routes/trips, no reports. A list-devices or find-device-by-name tool alone would fix most of the friction.

shanelord 14 days ago

I have "vibe coded" the fixes and put forward a PR for it. It will need thorough examination by a human programmer.
https://github.com/traccar/traccar/pull/5970

If you want to try it, change your repo to use ghcr.io/shanelord01/traccar:dev instead, then set up as follows:

1. Prerequisites

  • Running a build that includes this fork's fixes.
  • web.url set to your server's public HTTPS URL - this is what the OIDC issuer and MCP resource URLs are built from ({web.url}/api/oidc, {web.url}/api/mcp). Nothing else in this setup works without it.

2. Enable the MCP endpoint

<entry key='web.mcp.enable'>true</entry>

3. Register an OAuth client for your MCP client (e.g. Claude)

<entry key='openid.clients'>claude-mcp:<secret>:https://claude.ai/api/mcp/auth_callback</entry>

Format is clientId:clientSecret:redirectUri (this fork now rejects malformed entries with a clear error instead of a stack trace, so a typo here fails loudly). Generate the secret with:

openssl rand -hex 32

https://claude.ai/api/mcp/auth_callback is Claude's actual redirect URI - that's exactly what your working config uses. For multiple redirect URIs on one client, separate with |. For multiple clients, comma-separate whole entries.

Note this openid.clients key is unrelated to openid.clientId / openid.authUrl / etc. if you also have those configured (your instance does, for logging into Traccar itself via an external IdP) - that's Traccar acting as an OIDC client; openid.clients is Traccar acting as an OIDC server for MCP callers. Don't confuse the two.

4. Point the MCP client at your server

In Claude (or whatever MCP client), add a custom connector pointing at:

{web.url}/api/mcp

e.g. https://traccar.myserver.com/api/mcp.

Make sure you're logged into Traccar in the same browser before clicking through the MCP client's authorization flow - it relies on your existing Traccar session. Restart the container after config changes (config is only read on boot).

What's fixed vs. the forum thread

  • You no longer need the Traefik / nginx / Caddy path-rewriting workaround people were using - this fork serves discovery at both the bare and RFC 8414/9728-correct suffixed .well-known paths.
  • A malformed openid.clients entry now fails with a clear message instead of a raw stack trace.
  • Still an infra-level caveat from the thread, unrelated to this fork: it's worth checking if authorization silently fails after a delay with no MCP-side error - that points to the token exchange being blocked at Anthropic's infrastructure, not your server.

Once connected

Available tools: traccar-version, device-position, device-list, device-route, device-trips, device-summary. Server instructions and a trip-report prompt are built in to guide which tool to use for what.