Your GeoDynamics data, right inside your AI assistant
Connect GeoDynamics to Claude, ChatGPT or another AI assistant and ask about your people, hours, vehicles and sites in plain language. The assistant can only read, and only the data of your own company.
- Read-only: nothing gets changed
- Only your own company
- Sign in with your GeoDynamics account
https://mcp.geodynamics.dev/mcpConnect your assistant
Pick the assistant you use. You only need to do this once.
Using a coding agent? Paste one prompt and it sets itself up.
Claude (desktop app and claude.ai)
Add to Claude- Claude opens with everything filled in. Click Add.
- Click Connect, sign in with your GeoDynamics account and pick your company.
That's it: the connector now works on claude.ai and in the desktop app. Button not working? In Claude, go to Settings, Connectors, Add custom connector and paste the server URL from the top of this page.
On a Team or Enterprise plan, an owner adds it once for the whole organization, then everyone connects with their own account.
ChatGPT
ChatGPT can't fill in the details for you, so copy the server URL first:
https://mcp.geodynamics.dev/mcp- Click the + button and choose Add custom MCP server.
- Name it GeoDynamics and paste the URL you copied.
- Choose OAuth, confirm, click Create as a plugin and sign in with your GeoDynamics account.
If you don't see the option, your workspace admin may have to allow custom MCP servers first.
Cursor
Add to CursorCursor asks you to confirm, then opens the GeoDynamics sign-in the first time a tool runs.
Add it by hand instead
Put this in .cursor/mcp.json in your project, or in the global Cursor MCP config.
{
"mcpServers": {
"geodynamics": {
"url": "https://mcp.geodynamics.dev/mcp"
}
}
}VS Code
Add to VS CodeVS Code shows the server with an Install button, then asks you to sign in with your GeoDynamics account. Use the tools from Copilot Chat in agent mode.
Add it by hand instead
Put this in .vscode/mcp.json in your workspace.
{
"servers": {
"geodynamics": {
"type": "http",
"url": "https://mcp.geodynamics.dev/mcp"
}
}
}Claude Code
Run this in your terminal:
claude mcp add --transport http geodynamics https://mcp.geodynamics.dev/mcpThen start Claude Code, type /mcp, pick geodynamics and sign in.
Codex
Run this in your terminal:
codex mcp add geodynamics --url https://mcp.geodynamics.dev/mcpThen sign in once with codex mcp login geodynamics.
Using something else? See any other client in the developer notes.
A Monday morning with your assistant
Once connected, you just ask. Here is how a morning might go for someone in HR, and what the assistant looks up behind the scenes to answer.
- 09:15
How many hours did Tom work last week?
It finds Tom and asks GeoDynamics for his timesheet. The hours come from the same calculation your timesheet uses, so the number matches what you would sign off on. The assistant does not add up clockings on its own.
- 10:40
Compare Tom's hours with Sarah's over the whole month.
Two timesheets, side by side, in one answer. A single question covers up to 31 days, so for a longer stretch ask month by month.
- 11:20
Which vans do we have, and where are our depots?
Every vehicle with a tracker, and every site you set up in GeoDynamics: offices, depots and work sites. Handy when you plan who goes where.
More things to ask
- Who worked more than 45 hours last week?
- Show me Sarah's hours for the first week of the month.
- List all our work sites with "Ghent" in the name.
For developers
The first time a client connects, it signs in through OAuth with a GeoDynamics account (accounts.geodynamics.eu). Every tool call is then scoped to the companies linked to that account: a tool reads the company picked at sign-in, unless it gets acompanyId from listCompanies. Any other id is refused. Superadmin accounts are refused here: they belong on the Admin MCP. The server supports dynamic client registration, so clients register themselves.
Any other client
Clients that speak remote MCP take https://mcp.geodynamics.dev/mcpdirectly. Clients that only spawn a local process reach it through themcp-remote bridge.
npx -y mcp-remote@0.1.39 https://mcp.geodynamics.dev/mcp
Tool reference
Ten tools, all annotated read-only. Ids that one tool returns are the ids the next one accepts.
listCompanies The companies your account can read
No input. Returns companies, each with companyId, companyName and isDefault (the company picked at sign-in). Every other tool takes one of these as an optional companyId; without it, the tool reads the default company.
listUsers People in your company
Start here: the id it returns is the userId that getTimesheetSummary takes.
| Input | Type | Required | Notes |
|---|---|---|---|
search | string | optional | Filter by name or code, case-insensitive. |
page | integer | optional | 1-based. Default 1. |
pageSize | integer | optional | Default 50, max 100. |
Returns items, total, page, pageSize and hasMore. Each user has id, name, code, dayProgramId and mobilityRule (the name of the mobility scale, or null). Names are not unique: tell people apart by id.
getTimesheetSummary Worked hours for one person
From V5's timesheet reconstruction: worked hours, breaks, absences and overtime per day and for the period, the same numbers as the timesheet. For hours per activity or cost center, use the post-calculation tools below.
| Input | Type | Required | Notes |
|---|---|---|---|
userId | uuid | required | From listUsers. |
from | string | required | Start date, YYYY-MM-DD. |
to | string | required | End date, YYYY-MM-DD. Max 31 days from the start. |
Returns one row per day and the period totals, every duration in decimal hours: normalHours, grossWorkHours (break included), breakHours, netWorkHours, paid and unpaid absence, loadHours, mobilityHours, mobilityKm and movementKm (distance driven), overtimeHours, undertimeHours and balanceHours. Overtime and undertime are counted per day, so a period's overtime is not offset by its undertime; the balance is. A day without normal time, such as a weekend, has no overtime: its hours only count in the balance. Mobility hours are the fixed amount the mobility rule grants, not measured driving time.
listVehicles Vehicles with a tracking device
| Input | Type | Required | Notes |
|---|---|---|---|
search | string | optional | Filter by name, such as truck or van 12. |
page | integer | optional | 1-based. Default 1. |
pageSize | integer | optional | Default 50, max 100. |
Returns items, total, page, pageSize and hasMore. Each vehicle has id, name, code, unitId (the tracking device) and deviceType.
listPOIs Geofenced sites, offices and depots
The places clockings and vehicle movements are matched against.
| Input | Type | Required | Notes |
|---|---|---|---|
search | string | optional | Filter by name. |
typeName | string | optional | Filter by POI type, case-insensitive. |
city | string | optional | Filter by city, case-insensitive. |
page | integer | optional | 1-based. Default 1. |
pageSize | integer | optional | Default 50, max 100. |
Returns items, total, page, pageSize and hasMore. Each location has id, name, code, typeName, street, city, latitude and longitude.
listCostCenters Cost centers that post-calculation books hours against
Shows active cost centers only, unless you ask for expired ones too. A cost center without an expiration date never expires.
| Input | Type | Required | Notes |
|---|---|---|---|
search | string | optional | Filter by name or code, case-insensitive. |
includeExpired | boolean | optional | Also return expired cost centers, for historical post-calculation. Default false. |
page | integer | optional | 1-based. Default 1. |
pageSize | integer | optional | Default 50, max 100. |
Returns items, total, page, pageSize and hasMore. Each item has id, name, code, expirationDate, active, poi, autoCreate and creationDate, sorted by name, then code.
getHoursPerActivity Hours per activity over a period
From V5 post-calculation (nacalculatie): the hours V5 books per activity. For the whole company or one person, optionally split per person.
| Input | Type | Required | Notes |
|---|---|---|---|
from | string | required | Start date, YYYY-MM-DD. |
to | string | required | End date, YYYY-MM-DD. Max 31 days from the start. |
userId | uuid | optional | From listUsers. Default: everyone. |
perPerson | boolean | optional | Also split the totals per person. Default false. |
page | integer | optional | 1-based. Default 1. |
pageSize | integer | optional | Default 50, max 100. |
Returns totalHours and a page of totals (with totalCount, page, pageSize and hasMore), one row per activity (and person) with hours, normalWorkedHours, overtimeHours and days, largest first. hours also splits into workHours, directTravelHours, indirectTravelHours, indirectMobilityHours, loadUnloadHours and indirectAbsenceHours. An absence total carries absenceCode and absenceName; totals without hours are left out. If the company books no activities, the tool says so. days counts person-days: a total for the whole company counts every person's day with hours on it, a total for one person counts that person's days. A closed week is cached for a day, one that reaches today for ten minutes.
getHoursPerCostCenter Hours per cost center over a period
Same as getHoursPerActivity, grouped by cost center. Each total also carries fullCode, the cost center as V5 stores it; code is what the company's code pattern keeps of it, so two totals can share a code. fullCode matches code in listCostCenters, ignoring case. Absences sit on the absence cost center, told apart by absenceCode.
| Input | Type | Required | Notes |
|---|---|---|---|
from | string | required | Start date, YYYY-MM-DD. |
to | string | required | End date, YYYY-MM-DD. Max 31 days from the start. |
userId | uuid | optional | From listUsers. Default: everyone. |
perPerson | boolean | optional | Also split the totals per person. Default false. |
page | integer | optional | 1-based. Default 1. |
pageSize | integer | optional | Default 50, max 100. |
Returns the same shape as getHoursPerActivity, with the cost center code as code.
listReports The fleet reports you may run
The GeoDynamics fleet reports the signed-in user may run, filtered on their own V5 privileges. Five reports: Maintenance (next service per vehicle by date, km and hours), Mileage per vehicle per month, Mileage per vehicle per day, Export vehicle counters (km or machine hours per vehicle) and Vehicle overview (the fleet register: plate, VIN, fuel type, cost center). None of them contains clockings, positions, addresses or drivers.
Takes no input. Returns every report with its reportKey and what a run needs: vehicle (required or optional), period (day, month or none) and counters with their options.
runReport Run a report and read its data
Runs one report for one vehicle and one day or month and answers with its data as JSON, not as a file, so the agent reads the figures itself. Maintenance can run without a vehicle to check the whole fleet, and then returns only the tasks that are overdue or due soon. When the user has not said which vehicle, day or month, the agent asks first. Costs 5 of the 60 calls per minute.
| Input | Type | Required | Notes |
|---|---|---|---|
reportKey | string | required | One of ReportingMaintenance, ReportingMileagePerVehicleMonth, ReportingMileagePerVehicleDay, ReportingExportVehicleCounters or ReportingVehicleOverview. |
vehicleId | uuid | optional | From listVehicles. Needed when the report says vehicle: required. |
date | string | optional | The day, YYYY-MM-DD, for a report whose period is day. |
month | string | optional | The month, YYYY-MM, for a report whose period is month. |
counterIds | uuid[] | optional | From the report's counter options in listReports. Exactly one when it takes a single counter. |
Returns the report data as JSON: for Maintenance a list of tasks per vehicle with their status (overdue, warning or ok), for the other reports its sheets with one row per line.
Discovery
Agents that would rather not read this page can fetch the MCP Server Card athttps://build.geodynamics.eu/.well-known/mcp/server-card.json. It names the transport, the OAuth endpoints, and the same ten tools.