本文へ移動
🧾

Codex で plugin や MCP tool を使い始めると、単純な「実行してよいですか」だけでは足りなくなります。日付、金額、対象 repository、通知先、実行理由のように、tool を呼ぶ直前に人間が入力したい値があります。逆に、API key や OAuth のように、フォームへ入れてはいけない値もあります。

2026年8月の ChatGPT / Codex changelog では、Codex Remote 側に standard MCP forms と editable message approvals の対応が追加されています。これは便利な UI 改善ですが、運用では「入力欄が出せるようになった」だけで終わらせると危険です。フォームで集める値、承認文として編集できる値、URL へ逃がす値、監査ログに残す値を分ける必要があります。

この記事では、Codex の MCP forms と editable approvals の運用設計 に絞ります。MCP の input_required と再送の protocol 設計は MCP MRTR 設計ガイド、OAuth scope と token passthrough 禁止は MCP authorization / OAuth scope 設計ガイド、Codex 全体の sandbox と approval は Codex sandbox / approvals 設計ガイド、plugin の許可境界は Codex plugin governance 設計ガイド に分けています。

先に結論: form は入力欄、approval は実行許可として分ける

私なら、Codex の MCP form と approval を次のように分けます。

入口役割入れてよいもの入れてはいけないもの
MCP formtool 実行に足りない非機密パラメータを集める日付、選択肢、件名、上限金額、対象IDAPI key、password、access token
editable approval実行前の承認文や送信文を人間が直すPR comment、Slack draft、mail draft、理由説明承認済みでない scope 変更
URL mode機密情報や外部認可を別画面で扱うOAuth、payment、credential 登録client に見せたい通常入力
audit log後から判断を説明するrequester、server、tool、before/after、actionsecret 本文、フォーム全文の無制限保存

大事なのは、form を approval の代わりにしないことです。フォームに amount: 10000 と入れたからといって、その支払いが承認されたことにはなりません。入力は入力、承認は承認です。

standard MCP forms で何が変わるか

MCP の elicitation は、server が client を通じてユーザーに追加情報を求める仕組みです。form mode では、server が requestedSchema を出し、client が構造化された入力欄を表示できます。

たとえば、次のような値は form に向いています。

  • 対象 repository
  • ticket ID
  • review severity
  • dry-run か実行か
  • 通知先 channel
  • 上限件数
  • 実行予定日

これらは「LLM に自然文で聞く」より、form で選ばせる方が安全です。型、必須項目、選択肢、既定値を schema で固定できるからです。

一方で、form mode は in-band です。MCP client、transcript、debug log、tool result の周辺に値が残る可能性があります。MCP 仕様でも、password、API key、access token、payment credential のような機密情報は form mode で求めてはいけないと整理されています。

editable approvals は「送信直前の人間編集」に使う

editable message approvals は、Codex が作った送信文や action request を、人間が実行前に直せる導線です。これは、外部 write を伴う plugin / MCP tool で特に効きます。

たとえば次のような場面です。

  • GitHub PR comment を投稿する前に、断定を弱める
  • Slack 返信の宛先と文面を確認する
  • issue 作成前に、再現手順の欠落を足す
  • メール下書きから社外秘の表現を削る

ここでやってはいけないのは、編集可能な承認文へ新しい権限を紛れ込ませることです。たとえば最初は「PR にコメントする」承認だったのに、文面編集で「ついでに label を変更する」「branch を push する」まで含めるのは別 action です。承認単位を増やすなら、新しい approval request として出し直します。

form schema は UX ではなく安全境界として書く

MCP form の schema は、見た目を整えるためだけのものではありません。tool に渡せる値の境界です。

最初は次の制約を強めに置きます。

{
  "type": "object",
  "properties": {
    "target_repo": {
      "type": "string",
      "title": "Target repository",
      "pattern": "^[a-z0-9_.-]+/[a-z0-9_.-]+$"
    },
    "severity": {
      "type": "string",
      "title": "Severity",
      "enum": ["low", "medium", "high"]
    },
    "dry_run": {
      "type": "boolean",
      "title": "Dry run first",
      "default": true
    }
  },
  "required": ["target_repo", "severity"]
}

この例で見ているのは UI ではなく、事故半径です。

  • target_repo を自由入力にするなら形式を縛る
  • severity は enum にして表記揺れを消す
  • dry_run は default true にする
  • high のときだけ別 approval を要求する

AIエージェントに「適当に repository を選んで」と渡すより、form で人間に選ばせる方が、後から説明しやすくなります。

secret と OAuth は URL mode へ逃がす

API key、password、access token、payment credential は form に入れません。MCP の URL mode elicitation は、こうした機密情報や外部認可を MCP client の外へ逃がすための導線です。

実務では次の境界にします。

入力form modeURL mode
review 対象 branch○不要
実行理由○不要
Slack channel 名○不要
OAuth consent×○
API key 登録×○
payment credential×○

URL mode でも油断はできません。Codex や MCP client は、target domain を明示し、ユーザーが開く前に同意できる UI を出す必要があります。server 側は elicitationId と user identity を結び、session ID だけで状態を判断しないようにします。

approval log には before / after を残す

editable approval を使うなら、監査ログには「最終文面」だけでなく、少なくとも次を残します。

  • 元の proposed action
  • 人間が編集した後の final action
  • 変更した actor
  • 変更時刻
  • 対象 server / tool / connector
  • action kind
  • secret redaction の有無

たとえば PR comment の文面を編集したなら、before / after の差分は残します。ただし本文に secret や customer data が含まれる可能性がある場合、全文保存ではなく redacted diff と artifact pointer に分けます。ここは AIエージェント artifact retention 設計ガイド の領域です。

approval と form を分けた実務例

Codex automation に「PR コメントを見て修正し、必要なら返信案を作る」タスクを任せる場合、私は次のように分けます。

task:
  goal: respond_to_pr_feedback
  allowed_actions:
    - read_pr
    - edit_worktree
    - run_build
    - draft_reply
  forbidden_actions:
    - merge_pr
    - publish_release
    - send_reply_without_approval

mcp_form:
  fields:
    pr_number: integer
    max_files_changed: integer
    response_tone: enum
    dry_run: boolean

approval:
  required_for:
    - push_branch
    - post_pr_comment
  editable_message:
    - pr_comment_body

この設計なら、form は「何を処理するか」を固定し、approval は「外へ出すか」を止めます。Codex が修正した差分を build で検証するまでは、PR comment を投稿しません。

よくある失敗

1. form に secret を入れさせる

フォーム UI が出ると、つい API key を入力させたくなります。これは避けます。form mode の値は client 側に露出する前提で扱い、secret は URL mode、既存の connector 認可、または workspace 管理の secret store へ逃がします。

2. editable approval を「承認後の自由編集」にする

承認対象は、実行する action と対象 resource です。文面を直すのはよいですが、実行範囲を広げるなら新しい approval が必要です。

3. cancel と decline を同じ扱いにする

MCP elicitation には accept / decline / cancel の区別があります。cancel は「明示拒否」ではなく、閉じた、失敗した、後回しにした可能性があります。automation では cancel を retry loop に入れず、inbox へ戻す方が安全です。

4. form schema を自由入力だらけにする

自由入力欄ばかりだと、結局 prompt と変わりません。enum、boolean、min/max、format を使い、tool が受け取れる値を狭くします。

導入 checklist

  1. MCP server ごとに form mode / URL mode の対応を台帳化する
  2. form に入れてよい非機密 field を決める
  3. secret / OAuth / payment は URL mode か connector 認可へ逃がす
  4. editable approval で編集できる field を文面に限定する
  5. action scope が変わる編集は別 approval に戻す
  6. accept / decline / cancel を別状態として処理する
  7. before / after と actor を audit log に残す
  8. automation では未承認の外部 write を inbox へ戻す

まとめ

Codex の standard MCP forms と editable approvals は、MCP tool や plugin を実務で使いやすくします。ただし、便利な入力 UI と実行承認を混ぜると、何を人間が決め、何を agent が埋め、何が外部へ送られたのか分からなくなります。

form は非機密パラメータを構造化する場所。approval は外部副作用を止める場所。URL mode は secret と外部認可を逃がす場所。audit log は、後から判断を説明する場所です。

この4つを分けておけば、Codex に MCP tool を増やしても、便利さだけで権限境界が溶ける事故を避けやすくなります。

参考

WRITTEN BY nidoneko

Full-stack engineer with 8+ years of experience in TypeScript, React, Node.js, and cloud-native development across healthcare, finance, HR, and IoT domains.

View Profile →