Assertify について
Assertifyは、ユーザーがログインしたブラウザーセッションを通じて、AIエージェントがWebサイトを操作できるMCPサーバーです。セッションはローカルで暗号化され、ドメイン制限や重要操作の確認機能を備えています。
主な機能
- 01ローカルで暗号化したログインセッション
- 02Webページの閲覧と読み取り
- 03操作画面のスクリーンショット
- 04ドメインごとのセッション制限
- 05重要操作前の確認
- 06同一サイトの複数アカウント管理
活用シーン
- 01ログイン済みサイトのメッセージ確認
- 02Webページの検索と操作
- 03サイトのフォームからファイルをアップロード
- 04CAPTCHAや2FA時のセッション引き継ぎ
MCP 対応
ログイン管理、ページ確認、移動、操作などのブラウザーセッション用ツールをMCPクライアントに提供します。ローカルのstdioサーバーとして実行でき、任意のホステッドリレーはユーザーのPC上のコンパニオンに呼び出しを転送します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
Assertify
AI エージェントが、ログイン済みのあらゆるウェブサイトを使えるようにします。
一度ログインすれば、セッションはお使いのマシン上で暗号化されたまま保存されます。Claude、Codex、Cursor、その他あらゆる MCP クライアントが、代わりにページを閲覧したり、クリックしたり、入力したり、内容を読み取ったりできます。
クイックスタート · クライアントを接続する · ツール · セキュリティ · FAQ
You: Check my LinkedIn messages and summarize anything from recruiters.
Agent: open_session("linkedin") → click "Messaging" → read_text …
You have 3 recruiter messages. The most recent is from Dana at Acme, about a Senior QA role …
✨ Assertify を選ぶ理由
ほとんどのサイトには API がないか、必要な操作に対応していません。Assertify を使えば、パスワードを渡すことなく、あなたとしてすでにログイン済みの実際のブラウザーをエージェントに使わせることができます。
- 🔐 一度だけ手動でログインします。 通常のブラウザーウィンドウが開くので、サインインしてください(2FA、パスキー、SSO にも対応しています)。エージェントがパスワードを見ることはありません。
- 🧳 暗号化され、ローカルに保存され、あなたのものです。 セッションは、OS のキーチェーンに保存されたキーを使って AES-256-GCM で暗号化されます。Assertify 自体がデータを外部に送信することはありません。サーバーもアカウントも不要です。
- 🤖 あらゆる MCP クライアントで動作します。 Claude Code、Claude Desktop、Codex、Cursor、VS Code、Gemini CLI、Grok、Windsurf……
- 👀 エージェントが見ているものを確認できます。 各ステップでスクリーンショットを取得でき、チャットに表示されるほか、ディスクにも保存されます。
- 🛡️ 許可された範囲に制限されます。 各ログインはそれぞれのドメインに固定されるため、ページ上のプロンプトインジェクションで、ログイン済みのブラウザーを別の場所へ誘導することはできません。
- 👥 1つのサイトで複数のアカウントを使えます。 Gmail アカウントが5つありますか?それぞれにログインすると、メールアドレスが名前として使われます。1つだけ使うことも、すべて同時に開くこともできます。
- ✋ 操作の前に確認します。 送信、投稿、購入、削除、接続を行うボタンは、あなたが許可するまで一時停止します。ログインを読み取り専用にすることもできます。
- 🧍 人間のように動作します。 実際の Chrome を使い、独自のブラウザーフィンガープリント、カーブを描くマウス移動、不規則なタイピング、自然な間隔で操作します。
navigator.webdriverフラグはありません。 - 📎 ファイルやフォルダーをアップロードできます。 Facebook の投稿用の写真やメールに添付する PDF など、エージェントはあなたと同じようにアップロードボタンをクリックしてファイルを選択します。キーやパスワードのファイルは常に拒否されます。
- 🪟 ポップアップに対応します。 Cookie バナーは代わりに拒否します。「連絡先情報を共有」などのポップアップには目印を付け、エージェントが判断するか、閉じられるようにします。
- 🔁 必要に応じてあなたに操作を引き継ぎます。 CAPTCHA、2FA のプロンプト、期限切れのログインがあるとウィンドウが開き、あなたが操作を完了すると、エージェントが続行します。
- 🪶 高速で、トークンを節約できます。 エージェントが読むのは、生の HTML ではなく、簡潔な概要(
[e12] button "Send")です。
⚙️ 仕組み
flowchart LR
U(["👤 You"]) -- "log in once<br/>per account" --> L["Login window<br/><small>real browser, 2FA works</small>"]
L -- "named by<br/>email" --> V
K[["🔑 OS keychain<br/><small>macOS · Windows · Linux</small>"]] -. key .-> V
subgraph V["🔒 Encrypted vault"]
direction LR
P1["[email protected]"]
P2["[email protected]"]
P3["[email protected]"]
P4["[email protected]<br/><small>LinkedIn</small>"]
end
V -- decrypt --> S["⚙️ Assertify server<br/><small>asks before send · buy · delete</small>"]
A(["🤖 AI agent"]) <-- "pick one account<br/>or all at once" --> S
S -- "side by side" --> B
subgraph B["Headless browsers, logged in"]
direction LR
H1["Gmail · personal@"]
H2["Gmail · work@"]
H3["Gmail · shop@"]
end
classDef person fill:#eef2ff,stroke:#6366f1,color:#1e1b4b
classDef safe fill:#ecfdf5,stroke:#10b981,color:#064e3b
classDef live fill:#fff7ed,stroke:#f97316,color:#7c2d12
class U,A,L,S person
class P1,P2,P3,P4,K safe
class H1,H2,H3 live
style V fill:#f0fdf4,stroke:#10b981
style B fill:#fffbeb,stroke:#f59e0b
アカウントごとに一度ログインすると、それぞれのメールアドレスを名前として保存されます。エージェントは、名前でアカウントを1つ開くか、サイトの全アカウントをそれぞれログイン済みの専用ブラウザーで同時に開けます。上記の機能はすべて、macOS、Windows、Linux 上のお使いのコンピューターで動作します。
🚀 クイックスタート
uv が必要です。
- macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh - Windows(PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
git clone https://github.com/romaklym/assertify.git
cd assertify
uv sync
uv run assertify setup
setup はブラウザー(Chromium、約 300 MB、初回のみ)をダウンロードし、キーチェーンを確認して、AI クライアントを接続するための正確なコマンドを表示します。これを省略した場合、Assertify は初回使用時にブラウザーをダウンロードするか、インストール済みの Chrome または Edge を使用します。
Linux に関する注意
- ブラウザーが起動しない場合は、システムライブラリをインストールしてください。
sudo uv run playwright install-deps chromium - キーは Secret Service(GNOME Keyring または KWallet)に保存されます。キーチェーンのないサーバーでは、代わりに
ASSERTIFY_PASSPHRASEを設定してください。 - ログインにはブラウザーウィンドウを表示する画面が必要です。サーバーでは、デスクトップでログインして
~/.assertify-mcpを(同じパスフレーズを使って)コピーするか、ssh -Xを使用してください。
次に、最初のログイン情報を保存します。
uv run assertify login github https://github.com/login
ブラウザーウィンドウが開きます。サインインしたら、ウィンドウを閉じます(またはターミナルで Enter キーを押します)。これで完了です。エージェントがあなたとして GitHub を使えるようになりました。
ヒント
エージェントに「"log me in to Notion"」と頼むだけでも構いません。エージェントが
start_loginを呼び出すとウィンドウが開き、閉じたときにセッションが保存されます。
🔌 AI クライアントを接続する
/path/to/assertify をクローンした場所に置き換えてください(assertify setup で正確な行が表示されます)。
Claude Code
claude mcp add -s user assertify -- uv --directory /path/to/assertify run assertify serve
Claude Desktop
最も簡単な方法: assertify.mcpb をダウンロードしてダブルクリックします。Claude Desktop がアイコン付きでインストールし、Python も処理します。
または、claude_desktop_config.json に手動で追加します。
{
"mcpServers": {
"assertify": {
"command": "uv",
"args": ["--directory", "/path/to/assertify", "run", "assertify", "serve"]
}
}
}
Codex
codex mcp add assertify -- uv --directory /path/to/assertify run assertify serve
または ~/.codex/config.toml に追加します。
[mcp_servers.assertify]
command = "uv"
args = ["--directory", "/path/to/assertify", "run", "assertify", "serve"]
Cursor
~/.cursor/mcp.json:
{
"mcpServers": {
"assertify": {
"command": "uv",
"args": ["--directory", "/path/to/assertify", "run", "assertify", "serve"]
}
}
}
VS Code(Copilot)
.vscode/mcp.json:
{
"servers": {
"assertify": {
"type": "stdio",
"command": "uv",
"args": ["--directory", "/path/to/assertify", "run", "assertify", "serve"]
}
}
}
Gemini CLI、Grok、Windsurf、Zed など
ローカル(stdio)MCP サーバーを実行できるクライアントであれば、どれでも動作します。このコマンドを使用してください。
uv --directory /path/to/assertify run assertify serve
JSON 設定では、Cursor の項目にある mcpServers ブロックを使用してください。
| ツール | 機能 |
|---|---|
list_profiles(site?) | 保存済みのログイン情報(名前、アカウントのメールアドレス、サイト)を表示します。必要に応じて、1つのサイトのみに絞り込めます |
start_login(url, profile?) / complete_login | ログインするためのウィンドウを開き、セッションを暗号化して保存します。名前を指定しない場合は、アカウントのメールアドレスが名前になります |
rename_profile · delete_profile | 保存済みのログイン情報の名前を変更または削除します |
open_session(profile, url?, screenshots?) | ログイン済みのヘッドレスブラウザーを起動し、session_id とページの概要を返します |
open_sessions(site? | profiles?) | 複数のログインを一度に開きます(例:すべての Gmail アカウント)。各ログインに対して1つの session_id が割り当てられます |
snapshot | URL、タイトル、インタラクティブ要素を [e12] button "Save" の形式で表示します。ポップアップを優先し、CAPTCHA やサインインページには警告を表示します |
find(query) | ラベルを使ってページ全体の要素を検索します |
click · type_text · select_option · press_key · scroll · back · navigate · wait_for | 参照番号または表示テキスト(click(text="Messages"))で操作できます。小規模なデザイン変更でワークフローが壊れることはありません。各操作は最新の概要を返します |
upload_files(paths, ref? | text?) | サイトのファイルダイアログ(text="Photo/video")、アップロード欄、またはドラッグ&ドロップで、ファイルやフォルダー全体を添付します。添付のみを行います。投稿するには別途、確認済みのクリックが必要です |
dismiss_popup | 最前面のポップアップを閉じる/「Not now」ボタンで閉じます |
handoff(reason?) | 現在のページをあなた用のウィンドウで開きます(CAPTCHA、2FA、ログインの有効期限切れなど)。新たにログインすると、セッションに反映されます |
read_text | 信頼できないウェブサイトのコンテンツとしてマークされた、ページの表示テキストを取得します |
screenshot(ref?, full_page?) | ページまたは要素のスクリーンショットを撮影し、エージェントに表示するとともにファイルに保存します |
set_screenshots(enabled) | 各ステップにスクリーンショットを添付します(実行状況を確認するのに便利です) |
switch_tab | ポップアップは自動的にアクティブなタブになります。このツールで元のタブに戻します |
save_session / close_session | 更新された Cookie を保管庫に書き戻します(セッションを閉じると、デフォルトで保存されます) |
evaluate | ページ内で JavaScript を実行します。ASSERTIFY_ALLOW_EVAL=1 を設定しない限り、無効です |
👀 エージェントが見ているものを確認する
*「スクリーンショットを見せて」や「スクリーンショットを有効にして GitHub セッションを開き、処理を確認できるようにして」*と依頼してください。画像は、表示に対応したクライアントではチャットに表示され、すべて ~/.assertify-mcp/screenshots/<session>/NNN-<step>.jpg に保存されます。このフォルダーはあなた専用で、7日後に消去されます。
👥 1つのサイトで複数のアカウントを使う
アカウントごとに1回ログインします。名前を省略すると、Assertify はページ上で見つけたメールアドレスを各ログインの名前にします(サイトにメールアドレスが表示されない場合は、google.com-1、google.com-2…のようになります)。
assertify login https://mail.google.com # sign in as [email protected] -> saved as "[email protected]"
assertify login https://mail.google.com # sign in as [email protected] -> saved as "[email protected]"
assertify login work https://mail.google.com # or pick the name yourself
assertify list google.com # just the Google logins
assertify rename google.com-1 side-project
あとは、次のように依頼するだけです。
- 「[email protected] の受信トレイを確認して」:エージェントはそのログイン情報を開きます。
- 「Gmail アカウントのどれかに未読メールはある?」:エージェントは
open_sessions(site="google.com")を呼び出し、アカウントごとに1つのセッションを取得して、並行して確認します。
各アカウントはそれぞれ別の暗号化ファイルと分離されたブラウザーで管理されるため、Cookie が混ざることはありません。自動化を制限しているサイトでは、複数のアカウントで同じ操作を一度に実行しないでください。
📎 ファイルのアップロード
アップロードするファイルと保存先をエージェントに伝えます。
"~/Pictures/trip の写真を、キャプション「Back home」を付けて Facebook に投稿して"
エージェントは投稿画面を開き、upload_files(paths=["~/Pictures/trip"], text="Photo/video") を呼び出してキャプションを入力し、投稿をクリックする前にあなたに確認します。内部では、次のように動作します。
- まずファイルダイアログを表示します。 自然なマウスの動きでアップロードボタンをクリックし、ブラウザーのファイルダイアログでファイルを選択します。これは、ユーザーが操作したときにサイトが受け取るものと同じイベントです。
- 次に非表示のアップロードフィールドを使います。 多くのサイトでは、本物の
<input type="file">がボタンの背後に隠されています。Assertify はエージェントが指定した要素の近くにあるもの、または対象のファイル形式に対応するものを見つけます。 - 最後にドラッグ&ドロップします。 ドロップ専用エリアには、デスクトップからファイルをドラッグするようにドロップします(最大 50 MB)。
フォルダーを指定すると、隠しファイル(.DS_Store など)を除き、サブフォルダー内も含めてすべてのファイルが対象になります。単一ファイル用フィールド、ファイル形式の制限(accept="image/*")、フォルダー選択ダイアログにも対応しています。
アップロードできないもの: 隠しフォルダー(~/.ssh、~/.aws など)内のファイル、鍵、証明書、パスワードマネージャーのファイル、.env ファイル、ブラウザーの Cookie ストア、Assertify 自身の保管庫です。パスにはユーザーが指定したフルパスを使う必要があります。ページやメールで要求されたという理由でファイルをアップロードしないよう、エージェントには指示されています。制限は、1 回の呼び出しにつき 100 ファイル、2 GB です。許可するフォルダーを限定するには、ASSERTIFY_UPLOAD_DIRS を設定してください。
🧍 気付かれないようにする
サイトはロボットのように動作するブラウザーを検知します。Assertify は検知されないよう、次のように工夫しています。
- 実際の Chrome がインストールされていればそれを使用します(なければ Chromium にフォールバックします)。「自動化されたソフトウェアによって制御されています」というフラグや
navigator.webdriverは使用しません。 - あなたのフィンガープリント。 ログインウィンドウのユーザーエージェント、言語、タイムゾーンをエージェントのブラウザーで再利用するため、サイトからは同じ「デバイス」に見えます。
- 人間らしい入力。 マウスはボタン内のランダムな位置まで曲線を描いて移動し、キーは不規則な速度で 1 つずつ入力され、スクロールは小刻みに行われます。また、操作の合間やページの読み込み後には短いランダムな間隔を設けます。
- 速度制限。 ログインごとの 1 時間あたりのページ読み込み回数に上限を設けています(デフォルトは 400 回、自動化を禁止しているサイトでは 60 回)。
ASSERTIFY_HUMANIZE=0 を設定すると、人間らしい入力を無効にできます(高速になります。自分のツールやテストサイトで使う場合に適しています)。
🪟 ポップアップ、ダイアログ、期限切れのログイン
- Cookie バナーには「すべて拒否」/「必要なもののみ」を自動で選択します(無効にするには
ASSERTIFY_AUTO_CONSENT=0を設定します)。 - その他のポップアップ(ニュースレター、「連絡先情報を共有」、アプリの宣伝など)は、警告とともにスナップショット内の
## Pop-upに最初に一覧表示されます。エージェントは依頼内容に基づいて判断するか、dismiss_popupを呼び出します。ポップアップの背後に隠れた要素をクリックしようとすると、オーバーレイを黙ってクリックするのではなく、ヒントを表示して拒否します。 - ブラウザーダイアログ(
alert、confirm、「本当によろしいですか?」)はキャンセルして報告されます。意図した操作である場合、エージェントはaccept_dialog=trueを指定してクリックを繰り返します。 - CAPTCHA、2FA、期限切れのセッションがある場合、スナップショットに警告が表示されます。エージェントがこれらを解決しようとすることはありません。
handoffを呼び出すと、同じページを開いたウィンドウが画面に表示されるので、そこで操作を完了してウィンドウを閉じると、エージェントは新しい Cookie を使って処理を続けます。
⚖️ 責任を持って利用する
多くのサイトでは、利用規約で自動アクセスを禁止しています。LinkedIn、Facebook、Instagram、Threads、X、TikTok は明示的に禁止しており、違反したアカウントを制限することもあります。Assertify はこれらのサイトを認識し、動作を遅くしてページ読み込み回数の上限を引き下げ、タスクを小規模かつ個人的なものにするようエージェントに指示します。個人的な軽い利用(自分のメッセージの確認、自分のプロフィールの更新など)であれば通常は問題ありませんが、スクレイピング、一斉メッセージ送信、大量のつながり申請はアカウント制限の原因になります。利用するサイトの規約を守る責任はユーザーにあります。
🔒 セキュリティ
- 保存先:
~/.assertify-mcp/profiles/<name>.enc。AES-256-GCMで暗号化され、ファイルモードは0600、フォルダーは0700です。プロファイル名は暗号文に紐付けられているため、ファイルを入れ替えたり名前を変更したりできません。 - キー: OSのキーチェーン(macOS Keychain、Windows Credential Locker、Linux Secret Service)に保存されるランダムな256ビットキーです。キーチェーンがないマシンでは、代わりに
ASSERTIFY_PASSPHRASEを設定すると、scryptでキーが導出されます。 - ドメインガード: ログインの
allowed_domains以外への移動はブロックされます。デフォルトではログインURLのドメインとそのサブドメインが対象です。--domainで追加できます(SSOの場合など)。 - パスワードはコンテキストに含まれません: スナップショットでは、パスワードフィールドは
value=<hidden>と表示されます。 - テレメトリー、サーバー、アカウントは不要です。 使用するサイトへのご自身のブラウザ通信以外に、データがマシンの外へ送信されることはありません。
- 操作前に確認を求めます: 送信、投稿、購入、支払い、削除、接続、フォロー、申し込みなどのラベルが付いたボタンや、メッセージボックスでのEnterキーの押下は、エージェントが
confirmed=trueを指定して再度呼び出すまで保留されます。エージェントには、ユーザーの承認後にのみ指定するよう指示されます。 - 読み取り専用ログイン:
assertify login <name> <url> --read-only(またはstart_loginのread_only=true)を使うと、エージェントは閲覧と読み取りはできますが、入力、送信、投稿、購入はできません。 - アップロード: 使用できるのはフルパスのみです。秘密情報(隠しフォルダー、キー、
.env、Cookieストア、ボールト)はアップロードできません。シンボリックリンクは事前に解決されます。フォルダーの許可リストも設定できます(ASSERTIFY_UPLOAD_DIRS)。読み取り専用ログインではアップロードできません。 - 信頼できないページ: ページのテキストは、ウェブサイトのコンテンツであることを示すラベル付きで囲まれて返されます。また、エージェントには、ページ、メール、メッセージ内の指示には従わないよう指示されます。開けるのは
http(s)ページのみで、ダウンロードは無効です。
警告
保存されたセッションは、ログイン済みの状態と同じ力を持ちます。キーチェーンのロック解除中に、ユーザーとしてコードを実行できる人は誰でも、ブラウザのCookieを使う場合と同様にセッションを利用できます。信頼できるエージェントのみ接続してください。
脆弱性を発見しましたか?SECURITY.mdをご覧ください。
🎛️ 設定
| 変数 | 効果 |
|---|---|
ASSERTIFY_HOME | ボールトの場所(デフォルトは~/.assertify-mcp) |
ASSERTIFY_PASSPHRASE | OSのキーチェーンの代わりにパスフレーズを使用します |
ASSERTIFY_HEADED=1 | エージェントのブラウザーウィンドウを表示します(デバッグ時、またはヘッドレスをブロックするサイト向け) |
ASSERTIFY_SCREENSHOTS=1 | デフォルトで各ステップのスクリーンショットを撮影します |
ASSERTIFY_NO_AUTO_INSTALL=1 | Chromiumを自動ダウンロードしないようにします |
ASSERTIFY_ALLOW_EVAL=1 | evaluateツールを有効にします |
ASSERTIFY_ALLOW_ANY_DOMAIN=1 | ドメインガードを無効にします |
ASSERTIFY_HUMANIZE=0 | 人間らしいマウス操作、入力、一時停止を無効にします |
ASSERTIFY_BROWSER | chrome、chromium、またはmsedge(デフォルト:インストール済みならChrome、そうでなければChromium) |
ASSERTIFY_MAX_PAGES_PER_HOUR | ログインごとのページ読み込み上限(デフォルトは400、制限の厳しいサイトでは60) |
ASSERTIFY_AUTO_CONSENT=0 | Cookieバナーを自動で拒否しないようにします |
ASSERTIFY_UPLOAD_DIRS | これらのフォルダーからのアップロードのみ許可します(macOS/Linuxでは:、Windowsでは;で区切ります) |
ASSERTIFY_MAX_UPLOAD_MB | 1回の呼び出しあたりのアップロードサイズ上限(デフォルトは2048) |
CLI:assertify setup | login [name] <url> [--domain d] [--read-only] | list [site] | rename <name> <new> | delete <name> | serve。
❓ よくある質問
2FA、パスキー、「Google でログイン」に対応していますか?
はい。実際のブラウザーウィンドウでご自身でログインするため、そこでできることはすべて利用できます。サイトが SSO ドメインを経由する場合は、--domain で SSO ドメインを追加してください。
サイトからログアウトされたのはなぜですか?
セッションはサイト独自のスケジュールで期限切れになり、一部のサイトではときどき CAPTCHA や 2FA を再度求められます。その場合、エージェントが handoff を呼び出し、再度ログインするためのウィンドウが開きます。それ以外に必要な操作はありません。Assertify はセッション終了時に更新された Cookie も保存するため、継続中のセッションを維持できます。サイトがヘッドレスブラウザーを拒否し続ける場合は、ASSERTIFY_HEADED=1 を設定してください。
サイトのデザイン変更でエージェントが使えなくなりますか?
思ったほど影響はありません。エージェントは各ステップでページを新たに読み込み、固定セレクターの代わりに表示テキスト(click(text="Messages"))でクリックできるため、人と同じように対応します。大幅なデザイン変更では混乱することもありますが、何が見えているかを知らせてくれます。
スマートフォンやサーバーから利用できますか? まだできません。Assertify はローカルファースト設計のため、セッションがコンピューターの外に出ることはありません。
既知の制限 ログイン時に保存されるのは Cookie と localStorage であり、IndexedDB ではありません。そのため、トークンを IndexedDB のみに保存する一部のアプリではログイン状態を維持できません。検出回避は完全ではありません。自動化の検出を強く試みるサイトでは、検出される可能性があります。スナップショットは、まだ iframe や閉じたシャドウルートの内部を確認できません。
🤝 コントリビューション
Issue と PR を歓迎します。詳しくは CONTRIBUTING.md をご覧ください。概要は次のとおりです。
uv sync && uv run assertify setup
uv run pytest && uv run ruff check .
📄 ライセンス
MIT © Roman Klym
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。