ActivityWatch MCP Server

by 8bitgentleman

8 stars
273 downloads
Not rated
GitHub

About

Integrates with ActivityWatch to enable LLMs to interact with time tracking data, providing tools for listing buckets, executing AQL queries, and retrieving raw events for enhanced productivity analysis and time management.

Details

Author
8bitgentleman
GitHub stars
8
Downloads
273
Categories
Productivity, Other, Design, Developer Tools, AI, Infrastructure
Tags
#analytics, #data-analysis

- List Buckets: View all available ActivityWatch buckets
- Run Queries: Execute powerful AQL (ActivityWatch Query Language) queries
- Get Raw Events: Retrieve events directly from any bucket
- Get Settings: Access ActivityWatch configuration settings

Install via npm or build from source. Configure the server in your MCP client (e.g., Claude for Desktop) by adding it to the client’s config file. ActivityWatch must be running on http://localhost:5600.

An MCP server for ActivityWatch, allowing interaction with your personal time tracking data.

A Model Context Protocol (MCP) server that connects toActivityWatch, allowing LLMs like Claude to interact with your time tracking data.

- List Buckets: View all available ActivityWatch buckets
- Run Queries: Execute powerful AQL (ActivityWatch Query Language) queries
- Get Raw Events: Retrieve events directly from any bucket
- Get Settings: Access ActivityWatch configuration settings

You can install the ActivityWatch MCP server either from npm or by building it yourself.

# Global installation npm install -g activitywatch-mcp-server # Or install locally npm install activitywatch-mcp-server
git clone https://github.com/8bitgentleman/activitywatch-mcp-server.git cd activitywatch-mcp-server

- ActivityWatchinstalled and running
- Node.js (v14 or higher)
- Claude for Desktop (or any other MCP client)
-

Open your Claude for Desktop configuration file:

- Windows:%APPDATA%\Claude\claude_desktop_config.json
- macOS:~/Library/Application Support/Claude/claude_desktop_config.json

{ "mcpServers": { "activitywatch": { "command": "activitywatch-mcp-server", "args": [] } } }
{ "mcpServers": { "activitywatch": { "command": "node", "args": ["/path/to/activitywatch-mcp-server/dist/index.js"] } } }

Look for the MCP icon in Claude's interface to confirm it's working

Using a rootless podman container on Linux with Gemini CLI

Make sure to build the image first with:

version=$(npm pkg get version | tr -d '"') podman build . -t activitywatch-mcp-server:${version}

This example uses the override for Activity Watch not being available on127.0.0.1(see next section). If not required, you may omit theAW_API_BASEenvironment variable.

{ "mcpServers": { "activitywatch-mcp-server": { "command": "/usr/bin/podman", "args": [ "run", "--rm", "--interactive", "--userns=keep-id", "-e", "AW_API_BASE", "localhost/activitywatch-mcp-server:1.2.1" ], "env": { "AW_API_BASE": "http://mydesktop.local:5600/api/0" } } } }

If you want to run this MCP server from inside Windows Subsystem for Linux, for instance within a container, the AW server running in Windows will not be available at127.0.0.1. To override the standard localhost connection, use the environment variableAW_API_BASEor the--aw-api-baseflag, as below:

# Using environment variable export AW_API_BASE=http://mydesktop.local:5600/api/0 node dist/index.js # Or using command-line flag node dist/index.js --aw-api-base=http://mydesktop.local:5600/api/0

NOTE: The AW server may be fussy about the name used to connect to it, but it will accept a name that matches the computer name where it is running with a.localsuffix.

Here are some example queries you can try in Claude:

- List all your buckets: "What ActivityWatch buckets do I have?"
- Get application usage summary: "Can you show me which applications I've used the most today?"
- View browsing history: "What websites have I spent the most time on today?"
- Check productivity: "How much time have I spent in productivity apps today?"
- View settings: "What are my ActivityWatch settings?" or "Can you check a specific setting in ActivityWatch?"

Lists all available ActivityWatch buckets with optional type filtering.

- type(optional): Filter buckets by type (e.g., "window", "web", "afk")
- includeData(optional): Include bucket data in response

Run a query in ActivityWatch's query language (AQL).

- timeperiods: Time period(s) to query formatted as array of strings. For date ranges, use format:["2024-10-28/2024-10-29"]
- query: Array of query statements in ActivityWatch Query Language, where each item is a complete query with statements separated by semicolons
- name(optional): Name for the query (used for caching)

IMPORTANT: Each query string should contain a complete query with multiple statements separated by semicolons.

{ "timeperiods": ["2024-10-28/2024-10-29"], "query": ["events = query_bucket('aw-watcher-window_UNI-qUxy6XHnLkk'); RETURN = events;"] }

- timeperiodsshould have pre-formatted date ranges with slashes
- Each item in thequeryarray is a complete query with all statements

Get raw events from an ActivityWatch bucket.

- bucketId: ID of the bucket to fetch events from
- start(optional): Start date/time in ISO format
- end(optional): End date/time in ISO format
- limit(optional): Maximum number of events to return

Get ActivityWatch settings from the server.

- key(optional): Get a specific settings key instead of all settings

ActivityWatch uses a simple query language. Here are some common patterns:

// Get window events window_events = query_bucket(find_bucket("aw-watcher-window_")); RETURN = window_events; // Get only when not AFK afk_events = query_bucket(find_bucket("aw-watcher-afk_")); not_afk = filter_keyvals(afk_events, "status", ["not-afk"]); window_events = filter_period_intersect(window_events, not_afk); RETURN = window_events; // Group by app window_events = query_bucket(find_bucket("aw-watcher-window_")); events_by_app = merge_events_by_keys(window_events, ["app"]); RETURN = sort_by_duration(events_by_app); // Filter by app name window_events = query_bucket(find_bucket("aw-watcher-window_")); code_events = filter_keyvals(window_events, "app", ["Code"]); RETURN = code_events;

The server connects to the ActivityWatch API athttp://localhost:5600by default. If your ActivityWatch instance is running on a different host or port, you can override it as described in the Override ActivityWatch server host/port section above.

If ActivityWatch isn't running, the server will show connection errors. Make sure ActivityWatch is running and accessible at the specified host/port address (http://localhost:5600unless you have overridden it).

If you're encountering query errors:
- Check your query syntax
- Make sure the bucket IDs are correct
- Verify that the timeperiods contain data
- Check ActivityWatch logs for more details

If Claude reports errors when running queries through this MCP server, it's likely due to formatting issues. Make sure your query follows this exact format in your prompts:

{ "timeperiods": ["2024-10-28/2024-10-29"], "query": ["events = query_bucket('aw-watcher-window_UNI-qUxy6XHnLkk'); RETURN = events;"] }

- Time periods not formatted correctly (should be "start/end" in a single string within an array)
- Query statements split into separate array elements instead of being combined in one string

The most frequent error is when Claude splits each query statement into its own array element like this:

{ "query": [ "browser_events = query_bucket('aw-watcher-web');", "afk_events = query_bucket('aw-watcher-afk');", "RETURN = events;" ], "timeperiods": ["2024-10-28/2024-10-29"] }

This is INCORRECT. Instead, all statements should be in a single string within the array:

{ "timeperiods": ["2024-10-28/2024-10-29"], "query": ["browser_events = query_bucket('aw-watcher-web'); afk_events = query_bucket('aw-watcher-afk'); RETURN = events;"] }

When prompting Claude, be very explicit about the format and use examples. For instance, say:

"Run a query with timeperiods as["2024-10-28/2024-10-29"]and query as["statement1; statement2; RETURN = result;"]. Important: Make sure ALL query statements are in a single string within the array, not split into separate array elements."

Contributions are welcome! Please feel free to submit a Pull Request.

Manage forms, handle responses, and access analytics using the Fillout.io API.

Generates interactive sprint analytics and executive dashboards by connecting Jira data to Claude AI. Provides insights on burndown, velocity, and goal progress.

Triangulates customer support tickets and feature requests to generate prioritized product plans with convergence scoring and PII scrubbing.

Predict and track AI ROI using Monte Carlo simulations, real-time industry benchmarks, and ML-powered insights.

Automated document processing and extraction

Get clear, reliable and actionable Customer Insights with AI.

Great Question is an Agentic UX research platform for product builders. Its MCP lets AI agents create studies directly from any AI tool, surface insights, find the right research candidates, and query your entire research repository.

Honeydew semantic layer provides a governed, business-friendly data model that unifies metrics, dimensions, and relationships across sources, enabling consistent self-service analytics and AI-powered data access

Bring Kubit into your AI workflow - query your warehouse with natural language

Create and edit Tally forms and analyze submissions

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.