opal-mcp
Enables AI assistants to view screen time data and control focus blocks for the Opal app.
README
opal-mcp
Lets your AI assistant see and control your Opal screen time.
Ask Poke "how much time did I burn on Instagram this week" or "block me for an hour, I need to finish this" and it can actually answer and actually do it.
Works with Poke, Claude Desktop, OpenClaw, Hermes, or anything else that speaks MCP.
What it can do
| Tool | What it's for |
|---|---|
opal_status |
One call, whole picture. What's blocking, how long is left, today's total so far. Block status is this Mac only. |
opal_screen_time |
Time per app over any period. "today", "last 7 days", "this week", a date, a range. Covers your iPhone too. |
opal_list_schedules |
Your recurring blocks, when they run, which are paused. |
opal_blocked_apps |
What's on the blocklist right now. |
opal_start_block |
Start a focus block. Takes "45m", "1h30m", "2 hours", or a plain number. |
opal_stop_block |
End the block that's running. |
opal_check_setup |
What's working and what isn't. Run this when something's off. |
opal_debug_files |
Shows the shape of Opal's files. Only useful when a number looks wrong. |
Read this before you install it
Opal has no API. No developer docs, no keys, nothing to sign up for, and their terms say not to automate against their servers. So this doesn't talk to Opal at all. It works two other ways, both on your own machine:
- Reading your Opal data straight off your disk, where Opal already puts it. Read-only.
- Controlling blocks through Apple Shortcuts, which is the automation route Opal themselves point people at.
Two things follow from that, and they're worth knowing up front:
- It has to run on your Mac. It reads local files, so it can't run on a server somewhere. For Poke that means a tunnel — see below.
- Starting and stopping blocks needs Opal's Shortcuts actions, and those have shown up on iPhone and iPad before the Mac app. If the actions aren't in your Mac's Shortcuts app yet, reading works fine and controlling doesn't.
opal_check_setupwill tell you which situation you're in. There's no way around it from here — that part is Opal's to ship.
Reading your screen time works regardless.
Install
git clone https://github.com/lewisnsmith/opal-mcp.git
cd opal-mcp
npm install
npm run build
Then check what works on your machine:
npm run smoke
That starts the server the way an agent would and calls every read-only tool. It'll tell you what's missing.
Give it permission to read your screen time
The usage numbers live in a database macOS keeps locked down. Whatever app runs this server needs Full Disk Access:
System Settings → Privacy & Security → Full Disk Access, switch on the app that runs it — Terminal, iTerm, Claude Desktop, whichever — then restart that app. The restart matters, it won't take effect otherwise.
Without it you'll get a clear message saying so rather than a screen time total of zero.
Hook it up to Poke
Poke needs a public https URL, and this runs on your Mac, so you need a tunnel.
# terminal 1
MCP_AUTH_TOKEN=pick-a-long-random-string npm run serve
# terminal 2
cloudflared tunnel --url http://localhost:8000
Take the https URL cloudflared prints, then in Poke go to settings → connections → new:
- URL: the tunnel URL with
/mcpon the end.https://something.trycloudflare.com/mcp - Authorization:
Bearer pick-a-long-random-string
The /mcp is not optional. Leaving it off is the single most common reason Poke says it can't see any tools.
Then tell Poke: "use the opal integration's opal_status tool". Naming the integration explicitly helps the first time.
If Poke keeps acting like it's still looking at an old version of the connection, send it clearhistory.
ngrok http 8000 works the same way if you'd rather use that.
Hook it up to Claude Desktop, OpenClaw, or Hermes
These run things locally, so no tunnel and no token needed.
{
"mcpServers": {
"opal": {
"command": "node",
"args": ["/absolute/path/to/opal-mcp/dist/index.js"]
}
}
}
For Claude Desktop that goes in ~/Library/Application Support/Claude/claude_desktop_config.json. Other runners use the same shape — point them at the same command and args.
Your iPhone
Most people's screen time is mostly the phone, so this matters more than the Mac side.
Seeing your iPhone's screen time works already. Turn on Settings → Screen Time → Share Across Devices on the phone. Your iPhone usage syncs into the Mac's Screen Time store, and opal_screen_time reads it — you'll get one combined total with a per-device split, and device: "iphone" narrows to just the phone.
One thing worth knowing about how that's put together: several databases hold overlapping copies of this, so the numbers come from exactly one of them, never several added up. Summing them would count your Mac twice and inflate every total. The iCloud store wins when it's there, because it's the only one that knows about the phone.
Blocking your iPhone works through a Focus mode. Opal's Shortcuts actions only exist on iOS, so there's nothing on the Mac to call directly. The way round it:
- On the iPhone, open Opal and bind a block to a Focus mode — that's Opal's Focus Filter setting.
- On the Mac, make a shortcut with the Set Focus action turning that same Focus on. Name it
Opal Focus On. - Do it again for off, named
Opal Focus Off. - Check Focus is set to share across devices, or the Mac flipping it won't reach the phone.
Then opal_start_block flips the Focus, the Focus syncs to the phone, and Opal starts the block there.
The honest caveat: opal_status reads Opal's files on this Mac, so it can't confirm a block that's running on your phone. The tool says so in its reply rather than sending your agent looking for something it'll never find. Your iPhone's screen time still shows up fine — it's only the block status that's Mac-only.
Let it start and stop blocks
Reading works out of the box. Controlling needs a one-time setup, because the only sanctioned way in is Shortcuts.
- Open the Shortcuts app.
- New shortcut, add Opal's Start Session action.
- Name it exactly
Opal Start Session. - Do it again with End Session, named
Opal End Session.
Prefer different names? Set OPAL_SHORTCUT_START and OPAL_SHORTCUT_STOP instead.
If you can't find Opal's actions in the Shortcuts app, they aren't in your Mac build yet. See the note near the top.
Settings
All optional, all environment variables.
OPAL_TIMEZONE |
Which timezone your days run in. Defaults to your machine's. Get this wrong and every number lands on the wrong day. |
PORT |
HTTP port. Default 8000. |
HOST |
HTTP bind address. Default 127.0.0.1, so nothing off your machine can reach it directly. Tunnels connect to localhost, so you rarely need to change this. |
MCP_AUTH_TOKEN |
Require this as the bearer token in HTTP mode. Set it before you put a tunnel in front of this, or anyone with the URL can read your screen time and start blocks. |
OPAL_SHORTCUT_START |
Name of your start shortcut, if it isn't the default. |
OPAL_SHORTCUT_STOP |
Name of your stop shortcut. |
OPAL_MCP_DEBUG=1 |
Chattier logging, on stderr. |
When something's wrong
Run opal_check_setup first. It checks all three moving parts separately and names the broken one.
"Can't find Opal on this machine" — Opal needs to be installed and opened at least once, and this has to be running on that same Mac.
Screen time won't read — Full Disk Access, see above. Remember to restart the app afterwards.
Poke sees no tools — check the URL ends in /mcp, check the tunnel is still up, then send Poke clearhistory.
Numbers look wrong — run opal_debug_files. Opal never published their file format, so this shows what's actually on your disk. It prints key names only, never values, so it's safe to paste into an issue.
How much to trust this
Being straight with you about the shaky parts:
- The screen time numbers are solid. They come from the same macOS database System Settings reads, using a query that's been in forensics tooling for years.
- The Opal file parsing is educated guesswork. Opal doesn't document their format. The field names came from one small open source project doing the same thing, with nobody else to cross-check against. So every field is optional, one weird file can't take the rest down, and
opal_debug_filesexists for when it disagrees with reality. If you spot a wrong number, that tool's output is exactly what's needed to fix it. - Starting a block reports that the shortcut ran, not that Opal listened. Those aren't the same claim. Opal's harder modes are deliberately difficult to cancel, and that's the point of them. Check
opal_statusafter.
Development
npm test # 129 tests, no Mac required, uses fixtures
npm run typecheck
npm run dev # run from source over stdio
npm run smoke # check against your real machine
The tests build a real SQLite database with Apple's actual table names and run the real query against it, and stand up a real MCP client against both transports. They don't mock the parts that matter.
Licence
MIT
推荐服务器
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 模型以安全和受控的方式获取实时的网络信息。