macOS内部構造 · usernoted · SQLite

macOS通知センターのSQLiteデータベース(group.com.apple.usernoted)の仕組みと保存場所

macOSで「他のアプリの通知をトリガーに自動化したい」「通知履歴をスクリプトで取得したい」と調べると、必ず辿り着くのが usernoted のSQLiteデータベースです。macOS 15 Sequoiaにおける保存場所、テーブル構造、バイナリplistのデコード、そしてフルディスクアクセスを使わずに安全に読み取る方法を解説します。

brew install --cask n2ctech/tap/notiferry

最終更新: · macOS 15.0 以降対応 · 7日間無料トライアル

要点まとめ

  • macOS 15 Sequoiaの通知データベースは ~/Library/Group Containers/group.com.apple.usernoted/db2/db(WALモード)に保存されています。
  • macOSには他アプリの通知を購読する公開APIがないため、アプリ横断の通知転送にはこのSQLiteデータベースの読み取り専用参照が使われます。
  • NotiFerryはフルディスクアクセス(Full Disk Access)を要求せず、この単一フォルダへの読み取り専用アクセス権のみで新着通知をiPhoneへ転送します。

macOS 15 Sequoiaでの保存パス

macOSの通知センター(バックグラウンドデーモン usernoted)は、現在表示中・保留中の通知レコードをWAL(Write-Ahead Logging)モードのSQLiteデータベースに記録しています。macOS 15 Sequoiaでのパスは以下の通りです。

# macOS 15 Sequoia / macOS 14 Sonoma の標準パス(ユーザーコンテナ内)
~/Library/Group Containers/group.com.apple.usernoted/db2/db
~/Library/Group Containers/group.com.apple.usernoted/db2/db-wal
~/Library/Group Containers/group.com.apple.usernoted/db2/db-shm

# 旧バージョンのmacOSで使われていたキャッシュ領域の確認コマンド(参考)
ls -la "$(getconf DARWIN_USER_DIR)/com.apple.notificationcenter/db2/"

最新の通知は本体ファイル db にフラッシュされる前の db-wal(Write-Ahead Log)側に存在することが多いため、読み取る際は db だけでなくディレクトリ内の db-wal と db-shm も同じフォルダとして参照できる必要があります。

なぜmacOSには他アプリの通知を読む公開APIがないのか?

Androidにはシステム設定から許可できる NotificationListenerService がありますが、macOSの UNUserNotificationCenter は自アプリのバンドルID宛ての通知しか扱えません。

そのため、Mac上のあらゆるアプリ(Claude Code、Cursor、Xcode、Slack、ブラウザ、CLIツールなど)の通知を横断的に検知するには、画面上のUI要素をポーリングする(アクセシビリティAPI)か、usernoted のSQLiteデータベースを読み取るかの2択になります。画面ポーリングはバナーを非表示にしていると取得できない一方、SQLiteデータベースであれば着信時刻やアプリ識別子を正確に追跡できます。

主なテーブル構造(app・record)とバイナリplist

db2/db の中で特に重要なのは以下の2つのテーブルです。

  • app テーブル: app_id(整数主キー)と identifier(例:com.apple.dt.Xcode や com.todesktop.230313mzl4w4u92 などのバンドルID)を紐づけます。
  • record(または rec)テーブル: rec_id、app_id、delivered_date(Apple Core Dataエポック:2001年1月1日からの秒数)、および通知ペイロードを格納するBLOBカラム data を持ちます。

record.data カラムには、タイトル(titl)、サブタイトル(subt)、本文(body)などを含むバイナリ形式のプロパティリスト(bplist00)が格納されています。

# 読み取り専用(mode=ro)で最新の通知レコードとバンドルIDを確認する例
sqlite3 -readonly \
  "file:${HOME}/Library/Group Containers/group.com.apple.usernoted/db2/db?mode=ro" \
  "SELECT rec.rec_id, app.identifier, datetime(rec.delivered_date + 978307200, 'unixepoch', 'localtime') AS delivered_at, length(rec.data) AS plist_bytes
   FROM record AS rec
   JOIN app ON rec.app_id = app.app_id
   ORDER BY rec.rec_id DESC
   LIMIT 10;"

安全に読み取るための鉄則:読み取り専用と最小権限

usernoted のSQLiteを扱う際は、システムの安定性とセキュリティを守るために次の2点が不可欠です。

  • 必ず SQLITE_OPEN_READONLY で開く: システムデーモンとロック競合を起こさないよう、書き込みモードで開いたりスキーマを変更したりしてはいけません。
  • フルディスクアクセス(Full Disk Access)を避ける: 多くの自作スクリプト解説では「ターミナルにフルディスクアクセスを許可する」手順が紹介されていますが、フルディスクアクセスは連絡先、メッセージ履歴、ブラウザのCookie、SSH鍵などMac上のあらゆる保護データへのアクセス権を与えてしまいます。

NotiFerryがフルディスクアクセス不要で通知を転送する仕組み

NotiFerryは、この group.com.apple.usernoted フォルダを安全かつ手間なくiPhoneのntfyへ繋ぐために設計されたネイティブmacOSアプリです。

  • 単一フォルダの読み取り専用スコープ: 初回セットアップ時に標準のファイル選択ダイアログで group.com.apple.usernoted フォルダを1回選択するだけで、セキュリティスコープ付きブックマークとして読み取り専用アクセスを保持します。フルディスクアクセスは一切不要です。
  • 起動以降の差分のみを追跡: 過去の古い通知履歴を掘り起こすのではなく、転送を有効にした後に到着した新しいレコードだけを検知します。
  • プライバシーフィルタと10分ルール: 許可したアプリの通知だけを抽出し、選択したプライバシーモード(全文/アプリ名とタイトルのみ/汎用通知)を適用したうえでntfyへ送信します。オフライン時に10分以上経過した古い通知は遅延送信せず自動的に破棄します。
macOSメニューバー常駐

MacとiPhoneでの動作イメージ

macOSの通知センターフォルダに読み取り専用アクセスを許可し(フルディスクアクセス不要)、iPhoneの無料アプリ「ntfy」で専用トピックを購読します。テスト通知の受信を確認すると、7日間の無料トライアルが開始されます。

7日間無料トライアルをダウンロード
brew install --cask n2ctech/tap/notiferry
iPhoneに届く通知の例(ntfyアプリ内)
ntfyたった今

Claude Code — Permission required

Allow Bash tool in notiferry? · 全文表示 または タイトルのみ

ntfy · バースト集約2分前

Xcode — Build Succeeded (+4 earlier alerts)

macOS上のNotiFerryダッシュボード画面。通知転送が有効で、セッション中に9件の通知が転送され、プライバシーモードとiPhoneへのテスト送信ボタンが表示されている様子
macOS版NotiFerry:転送ステータス、プライバシーモード選択、iPhoneでのテスト受信確認。

よくある質問

macOS 15 Sequoiaで通知センターのデータベースはどこにありますか?

macOS SonomaおよびmacOS 15 Sequoiaでは、通知デーモン(usernoted)のSQLiteデータベースは ~/Library/Group Containers/group.com.apple.usernoted/db2/db(およびWALファイルの db-wal、db-shm)に保存されています。

他のアプリの通知を取得するためのApple公式API(UNUserNotificationCenterなど)はありますか?

いいえ。UNUserNotificationCenterは「自分のアプリ自身がスケジュール・受信した通知」しか取得できません。セキュリティとサンドボックスの境界により、macOSにはサードパーティ製アプリが他アプリの通知を購読するための公開API(AndroidのNotificationListenerServiceのような仕組み)は用意されていません。

usernotedのデータベースを直接書き換えたりDELETEしたりしても大丈夫ですか?

絶対に避けるべきです。usernotedデーモンがWALモードで常時書き込みを行っているため、外部プロセスから書き込むとデータベース破損や通知センターのフリーズを引き起こします。必ず読み取り専用(SQLITE_OPEN_READONLY / ?mode=ro)で開いてください。

このデータベースを読むにはフルディスクアクセス(Full Disk Access)が必須ですか?

ターミナルやバックグラウンドスクリプトから勝手に開く場合はTCC(プライバシー保護)にブロックされますが、ネイティブMacアプリでユーザーがファイル選択ダイアログ(NSOpenPanel)から group.com.apple.usernoted フォルダを明示的に選択し、セキュリティスコープ付きブックマーク(Security-Scoped Bookmark)を保存すれば、フルディスクアクセスを付与せずにその単一フォルダだけを読み取り専用で開くことができます。

ファウンディングリリース

SQLiteのポーリングスクリプトを自作・保守する代わりに。

7日間の無料トライアルは、テスト通知が実際にiPhoneへ届いたことを確認してから開始されます。その後は買い切りライセンス(€9.99・最大2台のMacで利用可能、サブスクリプションなし)で継続利用できます。購入後30日以内の全額返金保証付き(強行法規に基づく消費者の権利は影響を受けません)。

7日間無料トライアルをダウンロードまたは今すぐライセンスを購入 · €9.99
brew install --cask n2ctech/tap/notiferry
買い切り(サブスクなし) · 最大2台のMac · 定期的なオンラインライセンス認証