This MCP server provides read-only access to the Timing SQLite database on macOS. Use it to query time tracking data: app usage, window titles, durations, and project assignments.
list_timing_tables()— lists all tables in the databaseget_timing_schema(table_name)— returns column definitions for a tablequery_timing_db(sql_query, limit)— executes a read-only SQL query;limitdefaults to 200 rows, increase as needed for large date ranges
| Table | Description |
|---|---|
AppActivity |
Core records: app, window title, start/end timestamps, project |
Application |
App metadata: bundle ID, display name |
Title |
Window title strings referenced by AppActivity |
Project |
Timing projects for categorising entries |
TaskActivity |
Task-level time tracking |
All startDate and endDate fields in AppActivity are Unix timestamps (REAL). Always convert using:
datetime(startDate, 'unixepoch', 'localtime')Always exclude soft-deleted entries:
WHERE aa.isDeleted = 0The Title table uses stringValue for the window title string — not title.
-- Time spent per app today
SELECT app.title AS app,
ROUND(SUM(aa.endDate - aa.startDate) / 60.0, 1) AS minutes
FROM AppActivity aa
JOIN Application app ON aa.applicationID = app.id
WHERE aa.isDeleted = 0
AND datetime(aa.startDate, 'unixepoch', 'localtime') >= date('now')
GROUP BY app.title
ORDER BY minutes DESC;-- Activity log for a specific hour
SELECT datetime(aa.startDate, 'unixepoch', 'localtime') AS start,
datetime(aa.endDate, 'unixepoch', 'localtime') AS end,
app.title AS app,
t.stringValue AS window
FROM AppActivity aa
JOIN Application app ON aa.applicationID = app.id
LEFT JOIN Title t ON aa.titleID = t.id
WHERE aa.isDeleted = 0
AND datetime(aa.startDate, 'unixepoch', 'localtime') >= '2026-01-01 09:00:00'
AND datetime(aa.startDate, 'unixepoch', 'localtime') < '2026-01-01 10:00:00'
ORDER BY aa.startDate;