ActivityWatch MCP Server
A Model Context Protocol (MCP) server that connects to ActivityWatch, allowing LLMs like Claude to interact with your time tracking data.
README
ActivityWatch MCP Server
A Model Context Protocol (MCP) server that connects to ActivityWatch, allowing LLMs like Claude to interact with your time tracking data.
Version 2.0: Now implemented in Python with native UVX support! Originally built in TypeScript, this server has been completely rewritten in Python for better integration with the Python ecosystem and simplified deployment via
uvx.
<a href="https://glama.ai/mcp/servers/msnzvab06f"> <img width="380" height="200" src="https://glama.ai/mcp/servers/msnzvab06f/badge" alt="ActivityWatch Server MCP server" /> </a>
Features
- 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
- Query Examples: Get helpful examples of properly formatted queries
Installation
Using UV (Recommended)
When using uv no specific installation is needed. We will use uvx to directly run activitywatch-mcp-server-py.
uvx activitywatch-mcp-server-py
Using pip
Alternatively you can install activitywatch-mcp-server-py via pip:
pip install activitywatch-mcp-server-py
After installation, you can run it as a script using:
python -m activitywatch_mcp_server_py
Prerequisites
- ActivityWatch installed and running
- Python 3.10 or higher (automatically handled by uvx)
- An MCP client (Claude Desktop, OpenCode, Crush, etc.)
Configuration
Claude Desktop
Add to your Claude Desktop configuration file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
<details> <summary>Using uvx (recommended)</summary>
{
"mcpServers": {
"activitywatch": {
"command": "uvx",
"args": ["activitywatch-mcp-server-py"]
}
}
}
</details>
<details> <summary>Using pip installation</summary>
{
"mcpServers": {
"activitywatch": {
"command": "python",
"args": ["-m", "activitywatch_mcp_server_py"]
}
}
}
</details>
<details> <summary>With custom API endpoint</summary>
{
"mcpServers": {
"activitywatch": {
"command": "uvx",
"args": [
"activitywatch-mcp-server-py",
"--api-base",
"http://localhost:5600/api/0"
],
"env": {
"AW_API_BASE": "http://localhost:5600/api/0"
}
}
}
}
</details>
After configuration, restart Claude Desktop and look for the MCP icon to confirm it's working.
OpenCode
OpenCode supports MCP servers out of the box. Add the server configuration to your OpenCode settings:
<details> <summary>Using uvx</summary>
{
"mcp": {
"servers": {
"activitywatch": {
"command": "uvx",
"args": ["activitywatch-mcp-server-py"]
}
}
}
}
</details>
<details> <summary>Using pip installation</summary>
{
"mcp": {
"servers": {
"activitywatch": {
"command": "python",
"args": ["-m", "activitywatch_mcp_server_py"]
}
}
}
}
</details>
You can add this to:
- User Settings (JSON): Press
Ctrl+Shift+Pand select "Preferences: Open User Settings (JSON)" - Workspace Settings: Create
.vscode/mcp.jsonin your workspace
Crush
Crush also supports MCP servers. Configure it in your Crush settings:
<details> <summary>Using uvx</summary>
{
"mcpServers": {
"activitywatch": {
"command": "uvx",
"args": ["activitywatch-mcp-server-py"]
}
}
}
</details>
<details> <summary>Using pip installation</summary>
{
"mcpServers": {
"activitywatch": {
"command": "python",
"args": ["-m", "activitywatch_mcp_server_py"]
}
}
}
</details>
Available Tools
activitywatch-list-buckets
Lists all available ActivityWatch buckets with optional type filtering.
Parameters:
type(optional): Filter buckets by type (e.g., "window", "web", "afk")include_data(optional): Include bucket data in response
activitywatch-run-query
Run a query in ActivityWatch's query language (AQL).
Parameters:
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 semicolonsname(optional): Name for the query (used for caching)
IMPORTANT: Each query string should contain a complete query with multiple statements separated by semicolons.
Example request format:
{
"timeperiods": ["2024-10-28/2024-10-29"],
"query": [
"events = query_bucket('aw-watcher-window_hostname'); RETURN = events;"
]
}
Note that:
timeperiodsshould have pre-formatted date ranges with slashes- Each item in the
queryarray is a complete query with all statements
activitywatch-get-events
Get raw events from an ActivityWatch bucket.
Parameters:
bucket_id: ID of the bucket to fetch events fromstart(optional): Start date/time in ISO formatend(optional): End date/time in ISO formatlimit(optional): Maximum number of events to return
activitywatch-get-settings
Get ActivityWatch settings from the server.
Parameters:
key(optional): Get a specific settings key instead of all settings
activitywatch-query-examples
Get examples of properly formatted queries for the ActivityWatch MCP server. This tool takes no parameters and returns helpful examples.
Example Queries
Here are some example queries you can try:
- 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?"
Query Language Examples
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;
Configuration Options
The server connects to the ActivityWatch API at http://localhost:5600/api/0 by default.
You can customize this using:
-
Command-line argument:
uvx activitywatch-mcp-server-py --api-base http://localhost:5600/api/0 -
Environment variable:
export AW_API_BASE=http://localhost:5600/api/0 uvx activitywatch-mcp-server-py
Troubleshooting
ActivityWatch Not Running
If ActivityWatch isn't running, the server will show connection errors. Make sure ActivityWatch is running and accessible at http://localhost:5600.
Query Errors
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
- Use the
activitywatch-query-examplestool to see properly formatted examples
Query Formatting Issues
The most frequent error is when query statements are split into separate array elements instead of being combined in one string:
❌ INCORRECT:
{
"query": [
"browser_events = query_bucket('aw-watcher-web');",
"afk_events = query_bucket('aw-watcher-afk');",
"RETURN = events;"
],
"timeperiods": ["2024-10-28/2024-10-29"]
}
✅ CORRECT:
{
"timeperiods": ["2024-10-28/2024-10-29"],
"query": [
"browser_events = query_bucket('aw-watcher-web'); afk_events = query_bucket('aw-watcher-afk'); RETURN = events;"
]
}
Structure
Class Model
flowchart LR
subgraph "MCP Server"
direction TB
classDef server fill:#e1f5fe
classDef tool fill:#f3e5f6
classDef handler fill:#fff3e0
A[server.py] --> B[tools/]
A --> C[server.py]
class A server
class B tool
class C handler
end
subgraph "ActivityWatch API"
direction TB
classDef api fill:#e8f5e8
D[localhost:5600]
class D api
end
subgraph "MCP Client"
direction TB
classDef client fill:#fce4ec
E[Claude Desktop]
F[OpenCode]
class E client
class F client
end
A --> D
E --> A
F --> A
Project Structure
activitywatch-mcp-server/ ├── src/ │ └── activitywatch_mcp_server_py/ │ ├── init.py # Entry point and CLI │ ├── server.py # MCP server setup │ └── tools/ # Individual tool implementations │ ├── list_buckets.py │ ├── run_query.py │ ├── get_events.py │ ├── get_settings.py │ └── query_examples.py ├── tests/ # Test suite │ ├── conftest.py │ ├── test_list_buckets.py │ ├── test_run_query.py │ └── test_get_settings.py ├── pyproject.toml # Project configuration └── README.md
### Setup Development Environment
```bash
# Clone the repository
git clone https://github.com/8bitgentleman/activitywatch-mcp-server.git
cd activitywatch-mcp-server
# Create virtual environment and install dependencies
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install in editable mode with dev dependencies
uv pip install -e ".[dev]"
Running Tests
# Run all tests
pytest tests/ -v
# Run specific test file
pytest tests/test_list_buckets.py -v
# Run with coverage
pytest tests/ --cov=src/activitywatch_mcp_server_py --cov-report=html
# Run type checking
pyright src/
# Run linting
ruff check src/
Testing the Server Locally
# Run the server directly
source .venv/bin/activate
activitywatch-mcp-server-py
# Test with custom API endpoint
activitywatch-mcp-server-py --api-base http://localhost:5600/api/0
# Test with environment variable
AW_API_BASE=http://localhost:5600/api/0 activitywatch-mcp-server-py
Debugging
You can use the MCP inspector to debug the server:
npx @modelcontextprotocol/inspector uvx activitywatch-mcp-server-py
This will open a web interface where you can:
- See all available tools
- Test tool calls with custom parameters
- View request/response data
- Debug server communication
Adding New Tools
To add a new tool:
-
Create a new file in
src/activitywatch_mcp_server_py/tools/(e.g.,my_tool.py) -
Implement the schema function and handler:
from mcp.types import TextContent from typing import Any def my_tool_schema() -> dict[str, Any]: return { "type": "object", "properties": { "param": {"type": "string", "description": "Parameter description"} }, "required": ["param"] } async def my_tool_handler(api_base: str, arguments: dict[str, Any]) -> list[TextContent]: # Implementation here return [TextContent(type="text", text="Result")] -
Register the tool in
server.py:from activitywatch_mcp_server_py.tools.my_tool import my_tool_schema, my_tool_handler # In list_tools handler: Tool( name="activitywatch-my-tool", description="Tool description", inputSchema=my_tool_schema(), ), # In call_tool handler: case "activitywatch-my-tool": return await my_tool_handler(api_base, arguments) -
Write tests in
tests/test_my_tool.py
Release Process
The package is designed to be published to PyPI for easy installation via uvx:
# Update version in pyproject.toml
# Build the package
python -m build
# Upload to PyPI (requires PyPI credentials)
twine upload dist/*
# Test installation
uvx activitywatch-mcp-server-py
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。