screentime-mcp-server
# screentime-mcp-server
MCP server for querying macOS Screen Time data. Works with Claude Code, Claude Desktop, Cursor, and any MCP-compatible client.
Reads app usage data directly from macOS `knowledgeC.db` via `sqlite3` CLI — no native modules or dependencies required.
## Requirements
- **macOS** (Screen Time must be enabled)
- **Node.js** >= 18
- **Full Disk Access** must be granted to the host application (Claude Desktop, Terminal, etc.)
### Granting Full Disk Access
1. Open **System Settings** → **Privacy & Security** → **Full Disk Access**
2. Add the application that runs the MCP server (e.g., Claude Desktop, Terminal, WezTerm)
This is required because `knowledgeC.db` is in a protected location.
## Setup
### Claude Code
```bash
claude mcp add screentime -- npx -y screentime-mcp-server
```
### Claude Desktop
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"screentime": {
"command": "npx",
"args": ["-y", "screentime-mcp-server"]
}
}
}
```
### Cursor
Add to your Cursor MCP settings:
```json
{
"mcpServers": {
"screentime": {
"command": "npx",
"args": ["-y", "screentime-mcp-server"]
}
}
}
```
## Tools
### `get_screentime`
Get app usage data for a specific date with human-readable app names.
**Parameters:**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `date` | string | today | Date in `YYYY-MM-DD` format |
| `min_seconds` | number | 60 | Minimum usage duration in seconds |
**Example output:**
```
# Screen Time: 2026-02-14
**Total: 5h 30m**
- WezTerm: 2h 15m
- Arc: 1h 30m
- Ableton Live: 55m
- Obsidian: 50m
## Hourly Breakdown
- **09:00**: WezTerm 45m, Arc 12m
- **10:00**: Ableton Live 55m
- **11:00**: WezTerm 40m, Arc 18m
## Timeline Detail
- 09:05-09:50 WezTerm (45m)
- 09:50-10:02 Arc (12m)
- 10:02-10:57 Ableton Live (55m)
```
### `screentime_sql`
Run a custom SQL query directly against `knowledgeC.db`.
**Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `sql` | string | SQL query to execute |
**Schema notes:**
- Table: `ZOBJECT`
- Filter: `ZSTREAMNAME = '/app/usage'`
- App bundle ID: `ZVALUESTRING`
- Timestamps use Core Data epoch (add `978307200` to convert to Unix timestamp)
- Use `'localtime'` modifier for local timezone
## App Name Resolution
Bundle IDs are resolved to human-readable names using:
1. Built-in dictionary (common apps like Safari, Chrome, VS Code, Slack, etc.)
2. `mdfind` + `mdls` lookup (finds any installed app)
3. Fallback: last component of bundle ID, capitalized
## License
MIT
TDQS
Scored across 2 tools
get_screentime and screentime_sql have distinct roles: one is a convenience wrapper for date-specific usage, the other allows arbitrary SQL. However, an agent might be unsure when to use the specific date tool versus writing SQL, especially since both can return usage data.
The names follow different conventions: get_screentime uses a clear verb_noun pattern, while screentime_sql is noun-based and lacks a verb, making the set feel inconsistent. This mixing reduces predictability.
Two tools is quite thin for a server that could expose more granular Screen Time operations (e.g., date ranges, app lists, totals). The SQL escape hatch adds power, but the surface still feels minimal.
The combination of a targeted get_screentime tool and a general SQL query tool covers most retrieval needs, including custom queries. Minor gaps exist (e.g., no built-in date-range summary or app enumeration), but the SQL tool allows agents to compensate.