ChromeのMCPサーバーでWordPressにログインさせる

Googleが先日ChromeでMCPサーバーに対応という発表を行い、それによって「生成AIがChromeを操作できる???」と話題になりました。WordPressのようなCMSにとっては管理画面で行う操作が重要ですし、複数のプラグインの組み合わせがあるせいで単体テストでは解決できないバグもたくさん想定されますよね。なにより、Dev Toolsならスクリーンショットを撮ったり、さまざまな用途が想定されて夢が広がりまくりです。以前紹介したE2Eテストも必要ないのでは?

Chrome Dev Toolsを設定する

さっそく動作を検証してみましょう。まず必要なツールを紹介します。

  1. Google Chromeの最新版
  2. Node(20以上じゃないと動かないはず)
  3. Claude CodeやGemini CLIなどのMCPサーバーに対応した生成AIツール。デスクトップアプリだとClaude Desktopが対応してます。

インストールは簡単で、設定ファイルに記載するだけです。Claude Codeの例でいうと ~/.claude/settings.json に以下のように記載します。が、私の場合はなぜか ~/.claude/claude-code/mcp_settings.jsonが存在しています。

{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": ["-y", "chrome-devtools-mcp@latest"]
    }
  }
}

別のMCPサーバーはまりポイントもご紹介。私は、Voltaというnodeのバイナリ変更ツールを使っているのですが、これだとnpxコマンドが通らないケースがあったので、/Users/fumiki/.volta/bin/npx のように直接指定しています。まあ、動かない理由については生成AIに聞けば解決すると思います。

インストールが完了したら、Claudeを再起動して、/mcp の一覧を表示するとChrome Dev Toolsが表示されます。

Claude Codeで MCPコマンドを実行

Chrome Dev ToolsでWordPressにログインできない問題

Claudeに「ChromeでMCPサーバー使って確認して」と言えばブラウザが開きます。コンテキストドキュメント(CLAUDE.mdなど)にMCPサーバーのことを書いておけば「ブラウザで確認して」でも通じると思います。

Claudeが立ち上げたブラウザ。別プロファイルで動いてます。「自動テストソフトウェアによって制御されています」の文字。

これでもうすべての確認作業をChromeで行えるので、レイアウト崩れとかも直してくれるのではないか? そう思っていた時期が私にもありました。

さっそく会員制のWordPressサイトで「マイページ」の挙動を確かめてもらったところ、なぜかうまくいきません。

  1. テスト用のアカウントをローカルに作成し、認証情報をCLAUDEに教える。
  2. ログイン画面を表示して、認証情報を入力しようとする。ここまでは順調。
  3. フォーム送信後、ログイン画面に再度リダイレクトされる。「パスワードが間違っています」などのエラーが表示されるわけではない。

ここでかなりはまり、生成AI が「あきらめる」とか言い出しちゃったので、古のスキルGoogle検索に頼ることになりました。そして、ググり倒した結果、以下のことが判明。

  1. ClaudeがMCPサーバー経由でChromeを使う時、セッションを保持してるわけではなさそう。毎回新しいセッションとしている。
  2.  原因はCookieが保存されないこと。ログインできていないと判断され、管理画面からリダイレクトされている。

関連するGitHubイシューもありました。 Automatic connection to existing Chrome session (#140)

これがプロンプトやオプションの指定で解決する問題なのかわからなかったので、「ローカルのWordPressにmu-pluginsを作り、特定の定数が存在するときはそのユーザーとしてログイン扱いにする」という手段で解決しました。以下がそのプラグインです。

/**
 * 現在のユーザーを上書きする
 */
add_filter( 'determine_current_user', function( $user_id ) {
	if ( 'local' !== wp_get_environment_type() ) {
		// ローカル専用
		return $user_id;
	}

	// LOCAL_LOGGED_IN_AS 定数から対象ロールを取得
	if ( ! defined( 'LOCAL_LOGGED_IN_AS' ) || empty( LOCAL_LOGGED_IN_AS ) ) {
		return $user_id;
	}

	$login_as = LOCAL_LOGGED_IN_AS;

	// ロールごとのテストユーザー定義(必要なものをWordPressで事前に作っておく)
	$test_users = [
		'admin'      => 'test_admin',
		'editor'     => 'test_editor',
		'author'     => 'test_author',
		'subscriber' => 'rest_subscriber',
	];

	$username = $test_users[ $login_as ] ?? '';
	if ( empty( $username ) ) {
		return $user_id;
	}

	$user = get_user_by( 'login', $username );
	if ( ! $user ) {
		return $user_id;
	}

	// 既に同じユーザーIDが設定されている場合は何もしない。同一セッションでの実行を考慮。
	if ( $user_id && (int) $user_id === (int) $user->ID ) {
		return $user_id;
	}

	// 念のためCookieも発行してみる(これが現状で動かない部分)
	wp_set_current_user( $user->ID, $user->user_login );
	wp_set_auth_cookie( $user->ID, true );
	// ログインしているとされるユーザーのIDを返す
	return $user->ID;
}, 30 );

/**
 * auth_redirect() のオーバーライド
 *
 * Chrome DevTools MCPのようにクッキーを保持できない環境で、
 * wp-adminにアクセスできるようにする。
 * auth_redirectの中でwp_validate_auth_cookie()が走ってしまうため。
 *
 * ローカル環境でのみ動作。
 */
if ( ! function_exists( 'auth_redirect' ) && 'local' === wp_get_environment_type() ) {
	function auth_redirect() {
		// ログイン済みなら認証OK
		if ( get_current_user_id() ) {
			return;
		}

		// 未ログインならログインページへリダイレクト
		nocache_headers();

		$redirect = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
		$login_url = wp_login_url( $redirect, true );

		wp_redirect( $login_url );
		exit;
	}
}

これでいつでもユーザーの動作をトレースできますね。ただ、根本的にはMCPサーバー側で修正してもらわないと新規ユーザー登録フローとかを試せないので、修正を待ちたいですね。

ちなみにこの話題について今週10月16日(木)開催のWordPress Meetup東京で話しますので、お時間会う方はぜひお越しください。