Apple Safari について
macOS の Safari 向け MCP サーバーで、閲覧履歴、ブックマーク、リーディングリストに加え、開いているタブやページ内容を扱います。ファイル、Apple Events、拡張機能の各経路は異なるデータと操作を提供し、それぞれ権限が必要です。
主な機能
- 01履歴検索と訪問回数の確認
- 02タブ・ブックマーク・リーディングリストの一覧
- 03ページのテキスト・HTML・要素の取得
- 04オプションのページネットワーク記録
- 05書き込み有効時の URL 表示とページ操作
- 06ページ内コードの任意抽出
活用シーン
- 01以前訪れたページの検索
- 02開いているタブの内容やフォーム項目の確認
- 03許可したページのネットワークリクエストの確認
- 04書き込みを有効にしてフォーム入力や項目保存
MCP 対応
Safari の履歴、タブ、ブックマーク、リーディングリスト、ページ操作ツールを MCP クライアントに提供します。ページアクセス、ネットワーク記録、書き込み操作は別々の権限と設定で制御されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @mgcrea/mcp-apple-safariAPPLE_SAFARI_ALLOW_WRITESRegister the mutating tools. Off by default, and the gate decides whether the write tools exist at all rather than merely refusing — an agent with writes off cannot see them.APPLE_SAFARI_ALLOW_CODESReturn one-time codes: a one-time-code field in apple_safari_page_elements, and apple_safari_find_codes for a code a page shows as text. Its own gate rather than allowWrites, because it is a read. Credential fields stay redacted whatever this says.APPLE_SAFARI_ALLOW_NETWORKRegister apple_safari_network_record, _list and _get, which record what a page you allowed the extension on fetches and read the responses. Its own gate rather than allowWrites, because it is a read; off means the tools do not exist. Headers named like credentials are masked, bodies are not. Reloading a tab to record and saving a body to a file still need APPLE_SAFARI_ALLOW_WRITES.APPLE_SAFARI_DOWNLOAD_DIRWhere apple_safari_network_get's saveAs writes a file. Defaults to ~/Downloads. A name is kept to its basename and an existing file is never replaced unless asked.APPLE_SAFARI_NETWORK_CHUNK_CHARSCharacters of a body the server asks the page for per command when it reads a large body. Defaults to 262144, which was measured to work; how far above that Safari's native-message channel goes is unmeasured.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
@mgcrea/mcp-apple-safari
macOS の Safari ブラウザー向け MCP サーバーです。閲覧したページ、現在開いているページ、そして目の前に表示されているページの内容を確認できます。
{
"mcpServers": {
"apple-safari": { "command": "npx", "args": ["-y", "@mgcrea/mcp-apple-safari"] }
}
}
互いの代替にはならない3つの経路
何よりもまず理解しておくべきことです。このバンドルに含まれるその他のインターフェースでは、同じデータにアクセスする経路が2つあり、選択の基準は速度です。Safari の各経路が参照する情報はほぼ重複せず、それぞれ異なる権限が必要です。そのため、権限が付与されていない Safari サーバーは、単に動作が遅い Safari サーバーではなく、機能が大幅に限られた別のサーバーになります。
| 経路 | 必要なもの | 確認できる内容 |
|---|---|---|
| ファイル | フルディスクアクセス | 過去の情報:履歴、ブックマーク、リーディングリスト |
| Apple Events | Automation の許可、Safari の起動 | 現在の情報:開いているタブ |
| 拡張機能 | 拡張機能が有効で、そのサイトでの使用が許可されていること | ページの内容:テキスト、要素、ページ上での操作 |
拡張機能の経路に TCC の許可は一切必要ありません。Safari ではウェブサイトごとに許可を求めるため、ユーザーはサイトごとの許可を確認し、取り消すことができます。
ツール
読み取り
| ツール | 内容 |
|---|---|
apple_safari_search_history | テキストまたは日付範囲で履歴を検索し、訪問回数を表示します |
apple_safari_get_page | 参照 ID で履歴項目を1件取得します |
apple_safari_list_tabs | 現在開いているタブを一覧表示します。必要に応じて履歴の情報を追加します |
apple_safari_list_bookmarks | ブックマークのツリーを表示します |
apple_safari_list_reading_list | 保存済み項目と未読かどうかを表示します |
apple_safari_read_page | キャプチャしたページをテキストまたは HTML として読み取ります |
apple_safari_page_elements | 開いているページ上でクリックや入力が可能な要素を表示します |
apple_safari_diagnostics | 利用できる経路と、利用できない経路の理由を表示します |
オプトイン読み取り — APPLE_SAFARI_ALLOW_CODES
| ツール | 内容 |
|---|---|
apple_safari_find_codes | 開いているページのテキストから2FAコードを1回取得します |
オプトイン読み取り — APPLE_SAFARI_ALLOW_NETWORK
| ツール | 内容 |
|---|---|
apple_safari_network_record | ページの記録を開始、一時停止、消去、または状態報告します(reload には書き込み権限が必要です) |
apple_safari_network_list | ページが取得した内容を表示します:メソッド、URL、ステータス、所要時間。本文は含まれません |
apple_safari_network_get | リクエスト1件のヘッダーと本文を取得します。saveAs でファイルに書き込みます(書き込み権限が必要です) |
書き込み — APPLE_SAFARI_ALLOW_WRITES
| ツール | 内容 |
|---|---|
apple_safari_open_url | URL を新しいタブまたは現在のタブで開きます |
apple_safari_add_reading_list_item | URL を後で読むために保存します |
apple_safari_click | 開いているページの要素をクリックします |
apple_safari_fill | 入力欄にテキストを入力します |
apple_safari_scroll | ページをスクロールします |
設定
| Variable | Default | |
|---|---|---|
APPLE_SAFARI_ALLOW_WRITES | off | 5 つの書き込みツールを登録するかどうか。 |
APPLE_SAFARI_ALLOW_CODES | off | ワンタイムコードについては以下を参照してください。 |
APPLE_SAFARI_ALLOW_NETWORK | off | ネットワークキャプチャーについては以下を参照してください。 |
APPLE_SAFARI_DOWNLOAD_DIR | ~/Downloads | network_get の saveAs の保存先。 |
APPLE_SAFARI_NETWORK_CHUNK_CHARS | 262144 | 本文を取得する際のネイティブメッセージあたりの文字数。 |
APPLE_SAFARI_LIVE_TABS | on | Apple Events レーンを使用します。off = Apple Event を使用しません。 |
APPLE_SAFARI_STORE | auto | 明示的に指定する History.db のパス。 |
APPLE_SAFARI_BOOKMARKS | auto | 明示的に指定する Bookmarks.plist のパス。 |
APPLE_SAFARI_PAGES | auto | 明示的に指定する拡張機能のキャプチャーディレクトリ。 |
APPLE_SAFARI_ACTION_TIMEOUT_MS | 12000 | ページからの応答をアクションが待つ時間。 |
APPLE_SAFARI_LIVE_READ_TIMEOUT_MS | 2500 | タブ上で read_page が待つ時間。0 = キャプチャー。 |
APPLE_SAFARI_READING_LIST_CONFIRM_MS | 1500 | リーディングリストへの追加を確認するため、再読み込みまで待つ時間。 |
APPLE_SAFARI_INDEX_MODE | auto | auto | ro | immutable | off。 |
APPLE_SAFARI_DEFAULT_RANGE_DAYS | 30 | 開始日のみ指定された場合の期間。 |
APPLE_SAFARI_MAX_RANGE_DAYS | 3660 | 1 つの期間に設定できる上限。 |
APPLE_SAFARI_MAX_RESULTS | — | デフォルトのページサイズ。 |
APPLE_SAFARI_EXPOSE_PROMPTS | off | プロンプトと cupertino:// リソースを登録します。 |
APPLE_SAFARI_DEBUG | off | 詳細なログ出力。 |
APPLE_SAFARI_ALLOW_CODES
これをオンにすると、2 つの機能が連動します。find_codes が登録され、page_elements が
ワンタイムコード欄の値を返すようになります。これは読み取りであり、意図的に
ALLOW_WRITES には含めていません。書き込みゲートを通じて読み取りにアクセスするには、
数字を見るためにボタンをクリックする権限まで付与する必要があるためです。
認証情報欄は、どちらの場合も値を返しません。 パスワード、カード番号、CVC は
redacted: "credential" として返され、値も、それを返す設定もありません。このフラグは
コードを対象としており、それ以上に対象を広げることはありません。どちらの場合も、
hasValue は欄に値が入力されているかどうかを示します。通常は、それが必要な情報です。
同じ名前の Messages ゲートよりも制限が緩いため、その違いを把握しておく価値があります。
Messages では、オフにするとツール自体が存在せず、代わりにスレッド全体を調べる必要があります。
こちらでは read_page にゲートがないため、オフにすると対象の欄の読み取りとライブ DOM の
スキャンが無効になりますが、ページの全データが対象外になるわけではありません。
Passwords アプリ自体にどのレーンからもアクセスできない理由と、ウェブサイトに表示された
コードを読むことが、保管庫を読むこととは別の問題である理由については、リポジトリ内の
docs/passwords.md を参照してください。
APPLE_SAFARI_ALLOW_NETWORK
network_record、network_list、network_getを登録します。これらのツールでは、拡張機能へのアクセスを許可したページが取得した情報を確認できます。対象は、トップフレームからのfetchとXMLHttpRequestの呼び出し、コンソールエラー、リソースタイミングのエントリーです。これは読み取り用のゲートであり、ALLOW_WRITESには含まれません。ALLOW_CODESが含まれないのと同じ理由です。サインイン済みページの通信はセッション情報であり、1回限りのコードとは情報の露出が異なります。
- 本文もURLも編集されません。
authorization、proxy-authorization、cookie、set-cookieという名前のヘッダーや、token、secret、api-key、apikeyを含むヘッダーは、<redacted: N chars>として返されます。本文には照合する名前がないため、ページが受け取ったとおりに返されます。また、URLはクエリ文字列も含めて完全な形で返されるため、URLにトークンが含まれていれば、それも返されます。これを承知のうえでゲートを有効にしてください。 - タブごとに明示的な有効化が必要で、有効期限があります。
network_recordが開始されるまで、何もラップされません。記録はデフォルトで15分間(最長120分)リロード後も保持され、stopを実行すると直ちに終了します。 - さらに2つの操作には
ALLOW_WRITESも必要です。 ページを再実行するnetwork_recordのreload: trueと、APPLE_SAFARI_DOWNLOAD_DIRに書き込むnetwork_getのsaveAsです(ファイル名のみを指定し、overwrite: trueでない限り既存のファイルは上書きしません)。いずれもAPPLE_SAFARI_ALLOW_WRITESを示すエラーで失敗します。 - 確認できないもの: サブフレーム、ウェブワーカーとサービスワーカー、
<img>/<script>の本文、WebSocketです。ページのリロードや移動により、リクエストIDは無効になります。インラインスクリプトを拒否するContent-Security-Policyが設定されたページでは、代替手段としてURL経由でレコーダーを読み込みます。Safariでは検証されていません。動作する場合でも読み込みが遅いため、ページの最初のリクエストは記録されないことがあります。動作しない場合は、hook.injectionに"blocked"と表示されます。 - APIレスポンス内のファイル:
network_getで対象フィールドをjsonPathに指定し、decode: "base64"とsaveAsを使用します。バイト列はディスクに保存され、会話には入りません。
バッファーの上限は、ページあたり1,000件のレコードと本文50 MiBです。本文はmaxBodyBytesまで保持されます(デフォルトは10 MiB、上限は50 MiB)。docs/safari.mdを参照してください。
問題になりやすい注意点
- タブと一致しない履歴があっても正常であり、エラーではありません。 開いているタブと履歴を結び付けるキーはURLだけで、簡単に対応が失われます。測定した一致率は、3回の実行で60.7%、55.3%、**8.3%**でした。
pushStateで開いたシングルページアプリは履歴行をまったく記録しないため、実際にアクセスしたページがストアに存在しないこともあります。history: nullは「見つからない」と扱い、「アクセスしたことがない」とは決して扱わないでください。 - URLが完全一致しても、その行がそのページについてのものだとは限りません。 測定では、
http://localhost:4321/のタブが、まったく別のプロジェクトの履歴行と一致しました。ローカルアドレスでは、どれもこの可能性があります。 read_pageは、タブが応答できる場合はライブで読み取り、応答できない場合はスナップショットを読み取ります。 まず開いているタブに問い合わせ、APPLE_SAFARI_LIVE_READ_TIMEOUT_MSの時間だけ待ちます。表示中のタブは1秒以内に応答します。非表示のタブは10秒ごとにしか確認しないため、閉じたタブと同様に、拡張機能がページの読み込み時と読み込み完了時に保存したキャプチャが使われます。その理由はsource: "capture"、ageSeconds、liveReadで示されます。操作ツールは常にライブページに対して実行されるため、表示中のタブでは約1秒、非表示のタブでは最大10秒かかります。- フォームの読み取りには
read_pageではなくpage_elementsを使ってください。 フィールドの値はページテキストには含まれません。要素にはvalue(セレクトで選択中のオプションも含みます)、チェックボックスとラジオボタンのchecked、グレー表示されたコントロールのdisabled: trueが含まれます。グレー表示されたコントロールも除外されず、一覧に表示されます。値は、maxValueCharsで上限を引き上げない限り200文字で切り詰められます。切り詰められた場合はvalueTruncatedで示されます。 - フォームへの入力には
fillとclickを使ってください。fillは要素のネイティブセッターを通じて値を書き込みます。これによりReactが変更を認識します。単純にel.value =を実行するとテキストは表示されますが、Reactの状態は古い値のままです。セレクトでは、page_elementsが報告するオプションのテキストを指定します。チェックボックスとラジオボタンは入力ではなくクリックし、クリックすると状態が切り替わるため、先にcheckedを確認してください。ファイル入力は設定できません。コンテンツスクリプトからディスク上のファイルにアクセスする方法がないためです。 - 操作がタイムアウトした場合、待ち受けているものがなかったことを意味します。 拡張機能がオフである、対象サイトでの実行が許可されていない、またはページが閉じられた場合です。ページが操作を拒否したという意味ではありません。コマンドの実行は最大1回です。いったん渡されて失われたコマンドは再試行されません。クリックが実行された可能性がある場合に、繰り返してはいけないためです。
- 要素IDはページ遷移後に無効になります。 IDは
page_elementsの呼び出しで取得され、そのページでのみ有効です。自分でIDを作らず、何かを読み込んだクリックの後は必ず要素を再列挙してください。 - リーディングリストへの追加ではネットワーク通信が発生します。 Safariはエントリーを作成するため、バックグラウンドでURLを取得します。また、渡された
withTitleはページ独自のタイトルで上書きされます。verifiedは3つの状態を取り、falseになることはありません。ファイルへの反映は追加から約2秒遅れます。未確認の書き込みを失敗として報告すると、呼び出し元が再試行し、削除操作のないリストに重複して追加されるためです。 - 書き込み処理にフルディスクアクセスは必要ありません。 どちらのApple Events書き込みも、読み取り処理が動作しないマシンで実行できます。
APPLE_SAFARI_LIVE_TABS=falseは書き込みゲートより優先されます。このフラグは、Apple Eventを一切送信しないサーバーを保証するためです。 open_urlが受け付けるのはhttpとhttpsのみです。javascript:URLはフロントドア経由のdo JavaScriptに相当します。実測では、Safariはナビゲーション操作を通じてこれを受け付けます。また、file:はローカルファイルを読み込むナビゲーション操作です。
ライセンス
MIT。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。