開発misc-devメモ

2026年5月20日に、1Password が OpenAI Codex 向けに Environments MCP サーバーを公開した。記事は 1password.com/blog/1password-trusted-access-layer-for-openai-codex

ニュースだけ読むと「また MCP の連携先が増えた」程度に見えるが、中身を追うと AI コーディング環境で秘密情報を扱う設計が一段変わる話だった。普段から 1Password を使っていて、かつ Claude Code / Codex に作業を任せる頻度が増えている人ほど効いてくる。自分用のメモを兼ねて整理しておく。

ひとことで何が変わったか

軸は「誰が叩くインターフェースか」で見ると分かりやすい。

  • CLI 版 (op run 等): アプリの起動コマンドや CI から叩く。Vault の中身を実行プロセスへ直接注入する
  • MCP 版(今回の新機能): Codex / Claude Code 等の AI エージェントが叩く。Environment の作成・変数名の棚卸し・不足変数の検出ができ、値そのものは AI のコンテキストに出ない

つまり今回の発表は「op run の置き換え」ではなく、ブラウザ版 Codex のように CLI を叩けないクライアントや、AI エージェントに環境構築作業まで投げたい場面に、同等の操作を渡せる層を足した、という位置付けになる。

誤解されがちなこと — MCP は CLI / API の部分集合

ここは混同が多いので先に言っておく。

MCP でできることは、基本的に CLI / API でも全部できる。 逆は成り立たない(CLI でできて MCP に出ていない操作は普通にある)。

理由はシンプルで、MCP は AI クライアントが呼び出せるツールスキーマを並べたラッパーにすぎず、その実体は 1Password のバックエンド API / ローカルの op CLI を叩いている。MCP を入れたから新機能が増えた、ではない。「CLI を直接叩けない AI クライアント(ブラウザの Codex 等)からでも、同じ操作の安全なサブセットに触れる」というアクセス経路の話だ。

クライアント利用できる経路主な使い方
開発者(人)+ ターミナルCLI(op, op run起動コマンドへ秘密注入
Claude Code / Codex CLI(ローカル)CLI でも MCP でも可値の利用は CLI、管理操作は MCP が便利
ChatGPT 上の Codex(ブラウザ)等MCP のみ環境構築操作の遠隔実行
CI / Cloudflare Workers 等CLI / Service Account自動化パイプライン

なので「自分が使うべきは CLI か MCP か」を悩む必要はなく、両方入れて、用途で使い分けるのが正解。Web 版を使わない人は MCP に手を出さなくても困らない場面が多い。

なぜこれが要るのか — .env を AI に渡したくない問題

Codex や Claude Code に多くの作業を任せるほど、.env や設定ファイルに置いた秘密情報が事故の温床になる。具体的には次のような場面がじわじわ増える。

  • pnpm dev を AI に立ち上げさせるために .env.example を読ませる
  • API 連携のデバッグで「サーバーのレスポンス見せて」と指示してログを丸ごと貼り付けさせる
  • .gitignore の調整で .env の中身がうっかり差分に出る
  • セッションログがクラウドに残る環境で、トークンが要約・キャッシュに紛れ込む

「読み取り禁止ルール」を CLAUDE.md に書いて防ぐのが一番手堅いが、それでも完全には防ぎきれない。そもそも AI のコンテキストに秘密値を載せない仕組みがあれば、ルールに頼らずに済む。CLI / MCP どちらも同じ思想で動いている。

既存の op run でできていたこと

先に CLI 版の整理。1Password CLI の op run は、シェルから起動するアプリのプロセスに、Vault の中身を実行時だけ注入する。

# Secret Reference 記法
export GITHUB_TOKEN="op://development/GitHub/credentials/personal_token"
op run -- gh pr list

.env ファイルでまとめて指定する書き方もできる。

AWS_ACCESS_KEY_ID="op://development/aws/Access Keys/access_key_id"
AWS_SECRET_ACCESS_KEY="op://development/aws/Access Keys/secret_access_key"
op run --env-file="./prod.env" -- aws s3 ls

ポイントは3つ。

  1. プレーンテキストの値はディスクにもプロセスリストにも残らない
  2. プロセスが終われば環境変数も消える
  3. op run は PTY を挟んで stdout に値が出てもマスクする

「アプリ実行時の秘密注入」用途では今でもこれが最強で、pnpm devaws のような日常の起動コマンドはこれで足りる。

MCP 版が op run と被らない理由

ここからが本題。MCP 版は op run の置き換えではない。役割がずれている

op run(CLI)Environments MCP
主な用途アプリ起動時の秘密注入AI による Environment の作成・棚卸し
値の参照者アプリのプロセスアプリのプロセス(AIではない)
名前の参照者開発者本人AI エージェント
操作の承認シェル実行で暗黙承認操作ごとに 1Password の明示承認プロンプト

つまり MCP 版は「Codex / Claude Code に環境構築タスクを投げる」ための層であって、op run を捨てる話ではない。

公式の記述だと、MCP 経由で Codex は次のことができる。

  • Environment の作成(プロジェクト初期化時の「.env の代わり」役)
  • 変数名のリスト、不足変数の検出
  • リポジトリ内に紛れ込んだ平文 secret のスキャン候補出し
  • ステージ(dev / staging / prod)への横展開

そのいずれの操作でも、値そのものは AI のコンテキスト・ターミナル・ファイルに出ない。値の参照は最終的なアプリプロセス(=実行時)に限定される、という設計。op run と同じ「Just-in-Time」思想が、AI エージェントの操作面まで延長された格好だ。

セキュリティ上の意味 — 「永続的な認証情報はすでに侵害されている」

SiliconANGLE のインタビュー記事で 1Password CTO の Nancy Wang が「永続的な認証情報は既に危険にさらされている」と言い切っているのが、今回の方向性をよく表している。

AI が触る環境では、

  • セッションログがどこかに蓄積される
  • プロンプトキャッシュに値が残りうる
  • ローカルの .env を読ませた瞬間に、その値はモデルが「知っている」状態になる

という前提が崩せない。だったら最初から「短期間しか有効でない・タスク終了時に消える」前提で発行するしかない。1Password は同じ思想で Cursor、Browserbase、Perplexity の Comet ブラウザ等とも統合を広げており、AI 向けの secrets 取り扱いは「常時有効な API キーを .env に貼る」モデルから「タスクスコープでジャストインタイム発行」モデルへ寄っていく流れに見える。

自分の使い分け方針(暫定)

CLI 版と MCP 版の役割が違うので、両方入れて使い分ける。

  • pnpm dev / aws / gh 等の起動コマンドや CIop run --env-file=./dev.env -- で起動。これは人間が叩くか CI が叩くかで、AI を介す必要がない
  • AI に値を見せたくないが、AI が書いたコードを動かしたい → 出力は AI、起動は op run の組み合わせで分業
  • 新規プロジェクトの環境初期化 → 必要な変数の洗い出しと Environment への登録を Codex / Claude Code に MCP 経由で任せる
  • 平文 secret の棚卸し → 既存の .env を MCP 経由で Environment に移し、リポジトリから .env を抜く
  • ブラウザ版 Codex で作業 → CLI を叩けないので MCP 一択

op run の CLI フローと、MCP で AI に任せる管理フローが、Environment という同じ単位を共有するのが効いている。AI が触るのは「名前」と「構造」だけ、人間と CI とアプリが触るのが「値」、という分担になる。

税理士・会計士の実務に置き換えると

ここはフォロワー視点での余談。

会計事務所で API トークンが増える局面は、freee / マネーフォワード / e-Tax / 銀行スクレイピング系のサービスを横串で叩き始めるとき。「便利な顧問先別 Bot」を AI に書かせ始めた瞬間に、トークンの管理が一気に怖くなるのは、コードを書く人と書かない人の境目に立つ人ほど実感しやすいはず。

そこで op run と MCP 版の組み合わせは、

  • 顧問先ごとの API トークンを 1Password の Vault / Environment で分離
  • AI に「freee の月次 import スクリプトのひな形を書いて」と頼むとき、トークンの値そのものは AI に渡さない
  • 実行は op run -- python monthly_import.py でローカルから

という分業を、ルールではなく仕組みで縛れる。「顧客の機密データを AI に直接見せたくないが、便利は享受したい」という、いまの実務で一番モヤッとする部分にきれいに刺さる構造だと思う。

CLI 版 (op) を Windows に入れて使い始める手順

ここからは MCP ではなく、まず手元で確実に動く 1Password CLI(op)の導入を書く。デスクトップアプリの 1Password がすでに入っている前提。

1. インストール

Windows なら winget で入る。

winget install AgileBits.1Password.CLI
# もしくは
winget install --id 1Password.1PasswordCLI

確認:

op --version

2. デスクトップアプリと CLI を連携させる

これが一番重要なステップ。マスターパスワードを毎回入力したくないなら、デスクトップアプリ側で CLI 連携を有効化する

  1. 1Password デスクトップアプリを開く
  2. 設定(Settings) → 開発者(Developer)
  3. 「Integrate with 1Password CLI」 にチェック
  4. Windows Hello / 生体認証で承認を求められたら許可

これで op コマンドを叩いた瞬間にデスクトップアプリが指紋認証を要求してくる。シェルセッションごとに op signin を打つ必要が消える。

3. 動作確認

op vault list
op item list --vault Personal

ここまで動けば成功。Vault 名は自分の環境に合わせる。

4. Secret Reference を取得する

ブラウザ的に開かなくても、CLI から参照記法(op://...)が取れる。

# アイテムの詳細を見て、フィールド名を確認
op item get "GitHub" --vault Personal

# Secret Reference をクリップボードへコピー(GUI でもよい)
# デスクトップアプリのフィールド右クリック → "Copy Secret Reference"

GUI からコピーするほうが早い。フィールドを右クリックして 「秘密参照をコピー(Copy Secret Reference)」 を選ぶと、op://Personal/GitHub/credential のような文字列がクリップボードに入る。

5. op run で最小の動作確認

.env.template(コミットしてよい、値は参照だけのファイル)を作る。

GITHUB_TOKEN="op://Personal/GitHub/credential"

これを op run で実行コマンドに渡す。

op run --env-file=".env.template" -- gh auth status
op run --env-file=".env.template" -- gh pr list

実行中だけ GITHUB_TOKEN が解決された値として注入され、プロセスが終われば消える。echo $env:GITHUB_TOKEN で値を見ようとしても 1Password 側でマスクされる(PTY 経由のマスキング)。

6. 既存の .env を移行する

すでに平文の .env がある場合、次の順で移行する。

  1. .env の各値を 1Password に登録(Vault / Item / Field を決める)
  2. .env.template を作って op://... 参照に置き換える
  3. .gitignore.env を除外(既に除外されているか確認)
  4. 起動コマンドを op run --env-file=".env.template" -- <command> 形式に切り替える
  5. ローカルの .env を削除

ここまで来ると、リポジトリにもディスクにも平文の秘密値が無い状態になる。AI に repo 全体を読ませても事故らない。

CLI を税理士・会計士の RPA 用途で使う — 申告のお知らせ収集フロー(実走済み)

ここからは op CLI と Chrome DevTools MCP / agent-browser を組み合わせて、e-Tax の「申告のお知らせ」を顧問先ごとに自動収集するフローの設計図。最初は仮説で書いたが、ログインフォームまで実際に DOM を叩いて検証し、フロー図を修正した版を載せる。

実走で分かったこと(先に結論)

確認項目結果
法人ログイン URL(固定)https://login.e-tax.nta.go.jp/login/reception/loginCorporate
個人ログイン URL(固定)https://login.e-tax.nta.go.jp/login/reception/loginIndividual
利用者識別番号の inputname=oStUserId (type=tel, maxLength=16)
暗証番号の inputname=oStPassword (type=password)
disabled / readOnlyどちらも false。JS で .value 設定可
ログインボタンdisabled=false 初期から押下可能
フォーム送信標準的な HTML form。input イベントで値反映
ブラウザ拡張機能extension-is-installed=54 が検知される → マイナンバーカード認証ルート用。ID/PW 方式では拡張機能なしでもフォーム表示・入力は可能

つまり ID / 暗証番号方式のログインなら、oStUserIdoStPassword を埋めるだけで自動入力できる構造。Chrome DevTools MCP の fill_form や agent-browser でも、evaluate_script.value 直接代入 + input イベント発火でも通る。

修正版フロー

緑のノードが 1Password が効くポイント。橙のノードは「値を絶対に残さない」境界。

設計のキモ

  • 顧問先別の認証情報を Vault で分離し、Item 名を顧問先コードと一致させる(例: Vault eTax-Clients、Item client-0001
  • Item の field は oStUserId(識別番号16桁)、oStPassword(暗証番号)の2本に固定。フォーム input の name と一致させると op run 経由の注入がそのまま使える
  • Claude Code は op item list --vault eTax-Clients で**「顧問先コード・Item 名の対応」だけ読む**。値は読まない
  • 実際のブラウザフォーム入力は op run -- python collect.py のように起動側で値を注入。Python スクリプト → Chrome DevTools プロトコルで input に値を流し込む
  • 取得した「申告のお知らせ」PDF はファイル名に顧問先コードを付与して data/etax/<client>/YYYY-MM-DD.pdf に保存

コード例(最小)

.env.template(コミット可、値は参照だけ):

ETAX_USER_ID="op://eTax-Clients/$CLIENT_CODE/oStUserId"
ETAX_PASSWORD="op://eTax-Clients/$CLIENT_CODE/oStPassword"

起動コマンド:

CLIENT_CODE=client-0001 op run --env-file=".env.template" -- python collect_messages.py

Python 側は os.environ["ETAX_USER_ID"] / os.environ["ETAX_PASSWORD"] で受け取り、Playwright / Chrome DevTools プロトコルでフォームに流す。スクリプト自身も値を print しない・例外メッセージに含めないようにマスクする。

仮説段階で外したリスクと残ったリスク

  • 「ID/PW フォーム自体は自動入力できるか」 → DOM 検証で OK と判明
  • 「ログインボタンが初期 disabled で、特殊な活性化条件があるか」 → 初期から有効
  • ⚠️ マイナンバーカード認証必須の顧問先 → ID/PW 方式で代替不可。カードリーダー / スマホ認証が要るため自動化対象外。顧問先リストに認証方式フラグを付けて分岐するしかない
  • ⚠️ e-Tax の利用規約で第三者による自動操作が許容されるか → 税理士は「税務代理権限の範囲内」での代理ログインが認められているが、自動化 RPA については明文の許可は無い。実運用に乗せる前に顧問先ごとの代理権限と国税庁ヘルプデスクへの照会が必須
  • ⚠️ メッセージボックスの DOM 構造 → ログイン後の uketsuke.e-tax.nta.go.jp 側は未検証。次のステップで実顧客アカウント(自社)でログインして DOM を確認する必要あり
  • ⚠️ セッション再ログインの頻度・キャプチャの有無 → 同じく次回検証

次のアクション

  • 自社の e-Tax 法人アカウント(テスト用)でログインまでやり、メッセージボックス側の DOM を確認
  • 「申告のお知らせ」PDF のダウンロードリンク取得方法を確認
  • 利用規約・税務代理権限の整理(法務確認が先で、コードはその後
  • 確認できたら、このフロー図を「PoC 済み」に格上げして別記事に切り出す

利用条件のメモ

  • 個人アカウント・ビジネス・エンタープライズで利用可能(Enterprise は Environments のベータポリシーを有効化する必要あり)
  • セットアップ手順は 1Password Marketplace のリスティングから辿る
  • ローカル MCP 接続のため、1Password デスクトップアプリのインストールが前提

まとめ

  • MCP は CLI / API の部分集合。ターミナルで自分で叩ける環境では CLI で十分なケースが多い
  • MCP の存在意義は「CLI を叩けないクライアント(ブラウザ版 Codex 等)からも安全な操作を渡せる」こと、と「AI エージェントに環境構築作業を任せる」こと
  • AI には変数の名前と構造だけを見せ、値はプロセス起動時に注入する
  • .env を AI に読ませない」をルールではなく仕組みで実現できる
  • 税理士・会計士の RPA 用途(申告のお知らせ収集等)も、Vault 分離 + op run 注入の組み合わせで「顧客の認証情報を AI に見せない」分業が組める

CLI 版はまず winget install AgileBits.1Password.CLI → デスクトップアプリで「Integrate with 1Password CLI」をオンに、までやれば数分で動く。次の節で実走して、申告のお知らせ収集フローの仮説図を更新する。