A local read-only MCP server that exposes WakaTime coding activity to AI agents in Cursor, Claude, and other MCP clients.
Cursor / Claude / other MCP client
│
│ MCP over stdio
▼
Mediel.WakaTimeMcp
│
│ HTTPS REST API
▼
WakaTime
The server can report today's work, time over a date range, WakaTime projects, a business-client rollup, billing totals, and free time slots with no recorded coding activity.
It never writes to WakaTime. The API key is never stored in repository configuration.
MCP tools read the WakaTime API v1 (projects, summaries, durations) and return structured data:
- daily and range summaries
- mapping of several WakaTime projects onto one business client
- monthly billing from exact tracked seconds
- search for free gaps without WakaTime coding activity, including overnight slots and optional split packing
A free slot is only an interval with no recorded WakaTime coding activity. It does not prove that the user was otherwise idle.
.NET 10 SDK
WakaTime account
WakaTime API key
Cursor or another MCP client
The key is read only from the WAKATIME_API_KEY environment variable. Never put it in appsettings.json or git.
PowerShell example for a manual run:
$env:WAKATIME_API_KEY="YOUR_API_KEY"In Cursor, set the key in the MCP server env block, or as a user/system environment variable. Do not paste a real key into chat history or this README.
Committed WakaTimeMcp/appsettings.json and WakaTimeMcp/appsettings.example.json contain fictional example clients (Acme, Contoso, Northwind). Copy the example and replace it with your own mapping.
For a machine-local override that must not be committed, use WakaTimeMcp/appsettings.Local.json (already gitignored). If that file defines a Clients section, it replaces the example clients instead of merging with them.
{
"Clients": {
"Acme": {
"Aliases": [ "acme", "acme corp" ],
"ProjectPatterns": [ "Acme*" ],
"HourlyRate": 100,
"Currency": "USD"
}
}
}Important sections:
WakaTime.Timezone— defaultEurope/Prague.get_todayuses today in this timezone.Clients— business clients, wildcardProjectPatterns, aliases, hourly rate, and currency.GapSearch— daily search window for gap search, day-count limit, and in-memory cache TTL.dayEndmay be24:00.
dotnet restore
dotnet builddotnet testdotnet run --project WakaTimeMcp/WakaTimeMcp.csprojA normal dotnet run waits for MCP messages on stdin. That is expected STDIO transport behavior. Logs go to stderr; stdout stays reserved for the MCP protocol.
Point args at your local checkout of this repository.
{
"mcpServers": {
"wakatime": {
"command": "dotnet",
"args": [
"run",
"--project",
"C:\\path\\to\\WakaTimeMcp\\WakaTimeMcp\\WakaTimeMcp.csproj"
],
"env": {
"WAKATIME_API_KEY": "YOUR_API_KEY"
}
}
}
}dotnet publish WakaTimeMcp/WakaTimeMcp.csproj -c Release -r win-x64 --self-contained falseDefault output:
WakaTimeMcp/bin/Release/net10.0/win-x64/publish/Mediel.WakaTimeMcp.exe
{
"mcpServers": {
"wakatime": {
"command": "C:\\path\\to\\Mediel.WakaTimeMcp.exe",
"env": {
"WAKATIME_API_KEY": "YOUR_API_KEY"
}
}
}
}Place appsettings.json or appsettings.Local.json next to the executable if you copy it elsewhere.
| Tool | Purpose |
|---|---|
health_check |
Server status, timezone, API key configuration, WakaTime reachability |
get_projects |
List WakaTime projects |
get_today |
Coding activity for the local today |
get_time_range |
Aggregation for an inclusive date range |
get_project_summary |
Detail for one WakaTime project |
get_client_summary |
Rollup of all projects mapped to a client |
get_billing_summary |
Monthly billing draft |
get_billing_forecast |
Month-end projection from hours so far and remaining days |
get_clients |
Configured business clients and aliases |
get_unmapped_projects |
Projects that do not match any client pattern |
compare_periods |
Delta between two date ranges (B minus A) |
get_hour_distribution |
Coding time by local clock hour; NightSeconds is 22:00–06:00 |
get_quiet_days |
Calendar days with no recorded coding activity |
get_all_time |
Lifetime total from all_time_since_today |
get_stats |
Named-range stats (last_7_days, last_30_days, month, year) |
get_goals |
WakaTime coding goals and status |
get_insights |
One insight type (weekdays, best_day, languages, …) |
get_activity_timeline |
Busy/free timeline for one day |
find_free_slots_on_day |
Free gaps on one day (allowSplit can pack time into several gaps) |
find_free_slots |
Free gaps over a date range; touching overnight gaps are merged; dayEnd may be 24:00 |
Most summary, gap, and analytics tools accept optional writesOnly. When omitted, WakaTime uses the account preference. When true, only intervals with file writes are counted.
- Read-only against WakaTime. No write APIs are called.
- HTTPS is required for
WakaTime.BaseUrl. - The API key is sent as HTTP Basic
BASE64(key)and is never placed in query strings. - Do not commit
appsettings.Local.json,.env, or any file that contains a real key or real client rates you consider confidential.
See SECURITY.md to report a vulnerability.
The server uses the official ModelContextProtocol 2.2.0 NuGet package:
AddMcpServer().WithStdioServerTransport().WithToolsFromAssembly()- tool names via
[McpServerTool(Name = "...")] - instance tools with a DI constructor