はじめに
最近、draw.io MCP が公開されました。
これと Playwright MCP を組み合わせれば、
- 画面に遷移してスクリーンショット取得(Playwright)
- スクショに項番を付けたレイアウト図を作る(draw.io)
- HTML/画像を根拠にMarkdownの 画面設計書を書く (Copilot)
……までかなり自動化できそうだなと思い、休日を溶かして試したメモです。
先に結論
- 既存設計書がある中、保守目的で“更新”に使うにはまだ早い(特に「項番の一致」が不安定)
- 画面設計書がない(ないに等しい)プロジェクトで 0 → 1 を起こす用途なら、かなり使えそう
プロンプトやSKILLはすべて後述します。
「こうすればもっと良くなる」など、改善案もコメントいただけると嬉しいです。
前提
-
IDE:VS Code(GitHub Copilot Chat を使う)
-
Model:Claude Opus 4.5
-
Node(
npxが使える) -
OS:Windows(PowerShell 前提の手順を含みます)
-
画面設計書に最低限入れたいもの
- レイアウト図(フルスクリーンショット)
- 画面項目の一覧
- 操作イベントの一覧
ローカルMCPサーバはローカルで任意コードを実行し得るので、信頼できるものだけを使うのが前提です。
また、資格情報を .env で扱う場合は 誤コミット禁止(.gitignore)・共有時の取り扱いには要注意。
どうやって作らせる?
基本方針は次のとおりです。
- Playwright でアプリを操作(ログイン→対象画面へ遷移→スクショ取得)
- draw.io でフルスクショを下地にして、項番付きレイアウト図(PNG + drawio)を生成
- レイアウト図 + 画面HTMLを根拠に、テンプレに沿った画面設計書(Markdown)を生成
用意するもの
用意するファイルは大きく分けて2つ。
- MCP の設定を行う
mcp.json - Copilot がタスク実施時に読み込む
SKILL.md(Agent Skills)
1. .vscode/mcp.json
.vscode/mcp.json に、今回使用する draw.io MCP と Playwright MCP を記載します。
{
"servers": {
"playwright": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
},
"drawio": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@drawio/mcp@latest"]
}
}
}
2. SKILL.md(Agent Skills)
画面設計書作成は2つのMCPを使う複数手順で構成されます。
手順ごとに使わせたいMCPが決まっているため、SKILL.md に手順と利用ツールを厳密に記載する方が成果物が安定すると判断し、今回は SKILL.md ベースで進めます。
SKILL は2つ用意しています。
- 画面設計書作成用:情報収集→スクショ→レイアウト図→設計書生成まで
- 画面操作(Playwright)用:アプリ起動確認・起動・ログイン・ログアウトの“土台”
理由は、画面操作の部分は他用途でも使い回せそうなのと、全部1つにまとめるとボリュームが膨らみすぎるためです。
2-1. 画面設計書作成用 SKILL
ここでは、画面設計書作成時の手順を厳密に書きます。
- 対象画面の情報収集
- Playwright で画面操作とスクショ撮影
- draw.io でスクショを項番付きレイアウト図にする
- レイアウト図や画面項目などを含む設計書(Markdown)を生成する
「ファイルを作ってください」だけだと、失敗していても気づかず進むことがあります。
なので、PowerShell で 存在チェックや 埋め込み検証まで書くと安定しました。
SKILL.md 記載内容
.github/skills/screen-design-doc-generator/SKILL.md
---
name: screen-design-doc-generator
description: 画面設計書(Markdown)を作成します。Playwrightで対象画面のスクリーンショットを取得し、drawioでフルスクリーンショット上に項番(正方形+数字)を付与したレイアウト図(PNG)を作成したうえで、画面項目・入力規則・遷移・メッセージをテンプレートに沿って記述します。画面設計書の作成を依頼されたときに使用します。
---
# 目的
Webアプリの画面設計書を、一定の品質・粒度・形式で作成します。
# このスキルを使うタイミング
- 画面設計書の作成を依頼したとき
# 前提(入力として必要なもの)
ユーザーに不足があれば、作業開始前に質問して埋めてください(推測で埋めない)。
- 対象画面名(<screen-name> の命名も含む)
- 画面のURL(ログインが必要なら手順)
- 画面の目的(誰が/何をする画面か)
- 主要ユースケース(最大3〜5)
- 既存のテンプレート/フォルダ構成がある場合はそのパス
# 成果物(出力)
以下を作成/更新します(パスは必ずこの通りに統一)。
- `documents/design/ui-design/<screen-name>.md`(画面設計書)
- `documents/design/ui-design/assets/screens/<screen-name>_full.png`(フルスクリーンショット)
- `documents/design/ui-design/assets/screens/<screen-name>_<n>.png`(追加スクリーンショット:任意)
- `documents/design/ui-design/assets/layouts/<screen-name>.png`(drawioで作成したレイアウト図:フルスクショ+項番)
- `documents/design/ui-design/assets/layouts/<screen-name>.drawio`(編集用ソース)
# 作業手順
## 1. 対象画面の把握
- 画面の目的、利用者、前提条件(ログイン/権限/事前データ)を整理する
- 画面の主要ユースケース(最大3〜5)を箇条書きにする
## 2. Playwrightで画面キャプチャを取得
- 画面を開き、初期表示のフルスクリーンショットを撮る
- 可能なら以下も撮る(必要な範囲で)
- 画面内のモーダル
- バリデーションエラー表示
- 成功トースト/失敗メッセージ
- 取得した画像を `documents/design/ui-design/assets/screens/` に保存
- フルスクリーンショット:`<screen-name>_full.png`
- その他:`<screen-name>_<n>.png`(nは1始まりの連番)
## 3. drawioでレイアウト図(整形版)を作成(フルスクショ上に項番を付与)
### 3.0 目的
- `documents/design/ui-design/assets/layouts/<screen-name>.drawio` に **フルスクショ画像が埋め込み済み**で保存されること
- `documents/design/ui-design/assets/layouts/<screen-name>.png` が **確実にエクスポート**されること
- `<screen-name>.png` は「フルスクショを下地」+「項番(正方形)を最前面」で合成された一枚絵であること
- 項番の背景色は **透明度(Opacity)あり**とすること
### 3.1 入力画像(下地)のパス(固定)
- 下地画像:`documents/design/ui-design/assets/screens/<screen-name>_full.png`
### 3.2 drawio ソースの作成・保存先(固定)
- ソース:`documents/design/ui-design/assets/layouts/<screen-name>.drawio`
### 3.3 drawio での作業(必須:画像は「埋め込み」)
1. `documents/design/ui-design/assets/layouts/<screen-name>.drawio` を新規作成(または作り直し)して開く
2. **画像を埋め込みで挿入**する
- `documents/design/ui-design/assets/screens/<screen-name>_full.png` を drawio に挿入する
- 挿入時に「リンク」か「埋め込み」を選べる場合は、必ず **埋め込み(Embed)** を選択する
3. 挿入した画像を下地として整形する
- 画像をページの左上(原点)に配置する
- 画像がページ全体の下地になるよう、ページサイズを画像に合わせる(「ページを内容に合わせる / Fit to content」等)
- 画像は **最背面(Send to back)** に移動し、**ロック(Lock)** して以後動かないようにする
### 3.4 項番(正方形+数字)の付与(必須:最前面・透明度あり)
1. 項番は **正方形(square)** を使用する(円や吹き出しは禁止)
2. 正方形の中央に数字(`1, 2, 3...`)を記載する
- 文字は中央揃え
- 正方形サイズは全項目で統一する
3. 項番の背景色は **Opacity(透明度)を付ける**
- 例:Opacity 40〜60%(数値は任意だが必ず透明度あり)
4. すべての項番は **最前面(Bring to front)** に統一する
- 下地画像は最背面、項番は最前面
5. 項番は「画面項目表」の項番と一致させる
### 3.5 (任意)主要領域の枠
- 必要に応じて主要領域(ヘッダー/検索条件/一覧/フッター等)を枠で区切る(任意)
### 3.6 保存(必須:.drawio に画像が入っている状態で保存)
- `documents/design/ui-design/assets/layouts/<screen-name>.drawio` として保存する
- 保存後、**一度 drawio ファイルを閉じて再度開き**、フルスクショが表示されることを確認する
- 表示されない場合は「リンク保存」になっている可能性があるため、必ず「埋め込み」で挿入し直す
### 3.7 PNG エクスポート(必須:合成一枚絵)
- PNG の出力先:`documents/design/ui-design/assets/layouts/<screen-name>.png`
- エクスポートする PNG は **「フルスクショ + 正方形項番」が合成された一枚絵**であること
- エクスポート時は「ページ全体(Page)」を対象に出力する(画像だけ/選択範囲だけの出力は禁止)
### 3.8 エクスポート/埋め込みの検証(必須:失敗ならやり直し)
以下の PowerShell コマンドで成果物を検証し、満たさない場合は 3.6〜3.7 をやり直す。
```powershell
# 1) PNG が存在し、0バイトではないこと
$png = "documents/design/ui-design/assets/layouts/<screen-name>.png"
if (!(Test-Path $png)) { throw "PNG not exported: $png" }
if ((Get-Item $png).Length -le 0) { throw "PNG is empty: $png" }
# 2) drawio が存在すること
$drawio = "documents/design/ui-design/assets/layouts/<screen-name>.drawio"
if (!(Test-Path $drawio)) { throw "DRAWIO not saved: $drawio" }
# 3) drawio に画像が埋め込まれている可能性を確認(data:image を含むこと)
# ※埋め込み画像は drawio(XML) 内に data:image 形式で入ることが多い
if (!(Select-String -Path $drawio -Pattern "data:image" -Quiet)) {
throw "Screenshot is likely NOT embedded in drawio: $drawio"
}
"OK: layout png exported and screenshot embedded"
```
* 上記が通らない場合:
* `.drawio` を「埋め込み」で作り直し → 保存 → PNGエクスポート → 再検証
## 4. Markdown設計書を作成
- テンプレートに沿って記述する
- 推測で埋めない。不明点は **「要確認」** と明示するか、ユーザーに質問して確定する
## 5. セルフレビュー(品質チェック)
- 項番が「レイアウト図」と「画面項目表」で一致している
- 入力規則(必須/桁/形式/範囲)が漏れていない
- ボタン/リンクの挙動(押下後の遷移/更新/確認)が明確
- 文言(ラベル/メッセージ)が画面と一致(未確定なら要確認)
# 画面設計書テンプレート(この構造を守る)
```md
## <画面名> 画面設計書
### 1. 概要
- 目的:
- 対象ユーザー:
- 前提条件:
### 2. 画面レイアウト
<!-- フルスクショ上に正方形項番を付与したレイアウト図 -->
<img src="./assets/layouts/<screen-name>.png">
### 3. 画面項目
| 項番 | 項目名 | 種別 | 表示/入力 | 必須 | 型/形式 | 桁 | 初期値 | 入力規則 | 備考 |
|---:|---|---|---|:--:|---|---:|---|---|---|
| 1 | | テキスト | 入力 | | | | | | |
### 4. 操作・イベント
| 画面項番 | 操作 | トリガー | 条件 | 処理内容 | 成功時 | 失敗時 |
|---|---|---|---|---|---|---|
| 1 | 検索 | 検索ボタン押下 | | | | |
### 5. 補足
- 権限/ロール:
- 性能/制約:
- 要確認事項:
```
2-2. 画面操作(Playwright)用 SKILL
ここでは、Playwright が操作できる状態までを確実にします。
(起動確認→必要なら起動→ログイン→操作→ログアウト)
これがないと、Copilot が沼りがちです。
SKILL.md 記載内容
.github/skills/app-operation-playwright/SKILL.md
---
name: app-operation-playwright
description: Playwright(Playwright MCP)でローカル Web アプリ(http://localhost:8080)を確実に起動・ログイン・操作・ログアウトする手順
---
# App Operation via Playwright(画面操作手順)
## この SKILL の前提(重要)
- 対象URL:`http://localhost:8080`
- アプリ起動は **Windows PowerShell** を前提とします(コマンドも PowerShell を記載)。
- DB は **docker-compose.yml が存在** し、MySQL(`todo-chat` / `todo-chat-test`)を起動します。
- ただし **テスト用コンテナ(todo-chat-test)の health 待機は不要** です(要件として不要)。
- アプリ起動コマンドは以下です。
- `cd .\webapp\`
- `.\mvnw.cmd spring-boot:run`
- Java のバージョン指定は以下を **必ず実行** します(JDK 21 固定)。
- `$env:JAVA_HOME="C:\Program Files\Java\jdk-21"`
- `$env:Path="$env:JAVA_HOME\bin;$env:Path"`
## 目的
- Copilot が Playwright(Playwright MCP)を用いて、ローカルアプリを
**起動状態確認 → 必要なら起動 → ログイン → 画面操作 → ログアウト**
まで確実に実施できるようにします。
## 禁止事項
- **資格情報(ID/Password)の推測は禁止**(見つからない場合は止めてユーザー確認)
- **破壊的操作は禁止**(削除、退会、課金、管理者操作、データ変更など)
## Playwright の要素特定ルール(本アプリ前提)
本アプリの HTML には `data-testid` 等のテスト用属性が存在しないため、以下の順で特定します。
1. **ラベルと紐づく入力**(`label` → `input`)
2. **placeholder**(入力欄のヒント文字)
3. **name / id** 属性(フォーム部品が持っている場合)
5. **ボタンやリンクの表示テキスト**(例:`Login` / `ログアウト`)
`nth-child` や過度に長い CSS セレクタは使いません
---
# 作業手順
## 1. 事前に「起動済みか」を確認する(確実チェック)
### 1.1 HTTP 疎通確認(最優先)
**HTTP 200/3xx が返るなら起動済み**です。
```powershell
try {
$r = Invoke-WebRequest -UseBasicParsing http://localhost:8080/ -TimeoutSec 3
$r.StatusCode
} catch {
"NOT_RUNNING"
}
```
* 結果が `NOT_RUNNING` の場合 → 「2. 起動手順」へ
### 1.2 8080 LISTEN 確認(補助)
```powershell
netstat -ano | Select-String ":8080"
```
### 1.3 docker-compose のコンテナ起動確認(補助:DB 起動判定)
`docker-compose.yml` は DB 用です。
```powershell
docker compose -f .\docker-compose.yml ps
```
---
## 2. 起動手順(未起動の場合)
### 2.1 前提:Java 21 を必ず指定する
```powershell
$env:JAVA_HOME="C:\Program Files\Java\jdk-21"
$env:Path="$env:JAVA_HOME\bin;$env:Path"
java -version
```
* `java -version` の出力に **21** が含まれることを確認します。
### 2.2 DB(MySQL)を docker compose で起動する(確定手順)
#### 2.2.1 docker compose 実行(DB 起動)
```powershell
docker compose -f .\docker-compose.yml up -d
docker compose -f .\docker-compose.yml ps
```
#### 2.2.2 テスト用コンテナ(todo-chat-test)について
* `todo-chat-test` はテスト用のため **health 待機は実施しません**。
* 本番相当の DB として `todo-chat` が起動していることを `docker compose ps` で確認できれば十分です。
### 2.3 アプリ(Web)を起動する(確定コマンド)
```powershell
cd .\webapp\
.\mvnw.cmd spring-boot:run
```
### 2.4 起動完了(HTTP 応答)を確認する(確定待機)
アプリ起動後、`http://localhost:8080/` が応答するまで待機します。
```powershell
for ($i=0; $i -lt 120; $i++) {
try {
$r = Invoke-WebRequest -UseBasicParsing http://localhost:8080/ -TimeoutSec 2
if ($r.StatusCode -ge 200 -and $r.StatusCode -lt 400) { "OK: app is up"; break }
} catch {}
Start-Sleep -Seconds 1
}
```
---
## 3. ログイン手順(Playwright:確実フロー)
### 3.1 ログイン要否の判定(確実条件)
1. Playwright で `http://localhost:8080` を開く
2. 以下のどちらかで「ログイン画面」を断定する
* URL パスが `http://localhost:8080/login` と一致する
* ログイン画面 → 3.2 へ
* それ以外 → ログイン済みとして 4 へ
### 3.2 ログイン実行(資格情報は .env から取得)
#### 3.2.1 資格情報(確定情報)
資格情報は `.env` の以下キーから取得します(確定)。
| 資格情報 | ソース | キー |
| -------- | ------ | -------------- |
| username | `.env` | `APP_USERNAME` |
| password | `.env` | `APP_PASSWORD` |
#### 3.2.2 UI 操作(要素特定は REPLACE_ME を使用)
1. `#username` でユーザー名入力欄を特定し、username を入力
2. `#password` でパスワード入力欄を特定し、password を入力
3. ボタン表示が `Login` の要素をクリック
4. 成功判定(必須):
* URL パスが `http://localhost:8080/home` 以外になった、または
* ログアウト導線(`Logout`)が表示された
### 3.3 ログイン失敗時(確実対応)
* クリック後もログイン画面のままの場合:
1. 画面上のエラーメッセージを取得して記録する(スクリーンショットも取得)
2. `.env` の `APP_USERNAME` / `APP_PASSWORD` が正しいかをユーザーに確認する
3. CAPTCHA/MFA/SSO の表示がある場合は、自動化不可としてユーザーに指示を仰ぐ
---
## 4. 目的の画面操作(任意)
* 操作対象・成功条件(URL 変化 / 要素表示 / トースト表示など)を **必ず定義してから** 実行します。
---
## 5. ログアウト手順(Playwright:確実フロー)
### 5.1 ログアウト導線の特定
* 表示テキストが `Logout` の要素をクリックします。
### 5.2 成功判定(必須)
以下で判定します。
- URL パスが `http://localhost:8080/login` になった
---
## 6. トラブルシューティング(確実に切り分ける)
### 6.1 `http://localhost:8080` に繋がらない
1. 1.1 の HTTP 確認を再実行
2. 2.2 で DB が起動しているか確認(`docker compose ps`)
3. 2.3 のアプリ起動(`.\mvnw.cmd spring-boot:run`)が生きているか確認(起動ターミナルのログを確認)
4. 8080 を別プロセスが占有していないか確認(1.2)
### 6.2 docker compose が立ち上がらない
* `docker compose -f .\docker-compose.yml logs --tail=200` を確認し、環境変数(`MYSQL_*`, `TZ`)が解決できているかを確認
| 資格情報 | ソース | キー |
| -------- | ------ | -------------- |
| MYSQL_ROOT_PASSWORD | `.env` | `MYSQL_ROOT_PASSWORD` |
| MYSQL_DATABASE | `.env` | `MYSQL_DATABASE` |
| MYSQL_USER | `.env` | `MYSQL_USER` |
| MYSQL_PASSWORD | `.env` | `MYSQL_PASSWORD` |
### 6.3 UI 要素が見つからない / クリックできない
* スクリーンショットを取得して「実際に表示されている文言 / ラベル / placeholder / name / id / aria-label」を確認します。
* 待機が必要な場合は、**待機条件(要素の表示/非表示)を明示して** 待機します。
---
## 7. 実行チェックリスト(完了条件)
* [ ] Java 21 が有効(`java -version` に 21)
* [ ] `docker compose -f .\docker-compose.yml ps` で `todo-chat` が `running`
* [ ] `http://localhost:8080/` が 200/3xx 応答
* [ ] ログイン成功判定を満たした(URL or ログアウト導線表示)
* [ ] ログアウト成功判定を満たした(URL or ログイン画面識別要素表示)
補足(資格情報とOS差分)
資格情報を Copilot が取得するにあたって .env を読ませていますが、.env.copilot のように Copilot用を分離するのが望ましいと思います。
また今回は Windows 前提なので、Mac/Linux を想定するならコマンド部分の記載を分ける必要があります。
成果物
SKILL を作成後、あとは作ってほしい画面の情報を Chat に投げます。
# 依頼内容
タスク一覧の画面設計書を作成してください。
# 前提
- 画面名: タスク一覧
- URL: http://localhost:8080/task
- 画面の目的: ログインユーザーの作成したタスクを一覧表示し、また検索機能を提供する
- 主要ユースケース
- タスクを検索する
- 検索項目はタイトル、ステータス、開始日時のFrom~To、終了日時のFrom~To
- タイトル以外の項目は詳細検索項目
- 表示されたタスクは参照画面へ遷移できる
- HTMLのパス: webapp/src/main/resources/templates/task/index.html
すると、おおよそ20分後に以下の5ファイルを生成してくれました。
| ファイル | パス |
|---|---|
| 画面設計書 | documents/design/ui-design/task-list.md |
| フルスクリーンショット | documents/design/ui-design/assets/screens/task-list_full.png |
| 詳細検索展開時スクリーンショット | documents/design/ui-design/assets/screens/task-list_1.png |
| レイアウト図(PNG) | documents/design/ui-design/assets/layouts/task-list.png |
| レイアウト図(drawio) | documents/design/ui-design/assets/layouts/task-list.drawio |
task-list.md はこんな感じ
まとめ
まずは良い所
-
レイアウト図の生成以外は、ほぼ完ぺき
- 作成された画面設計書の構成は SKILL.md に記載したテンプレートに準拠している
- 設計書に記載すべき画面項目の取捨選択も高精度
- 検索項目は全網羅できている
- 入力に記載しなかったヘッダーやフッター部分の項目についても連番を振ってくれている
- 操作・イベントセクションの記載内容は完璧
- 画面項番との紐づきも間違いはない
- 処理内容も実装と相違なし
つまり、Playwright による画面操作が成立していて、文章(仕様の記述)が安定して正確なので、画面設計書がない状態から 0 → 1 を起こす用途ではかなり有効。
レイアウト図が未完成でも、生成される documents/design/ui-design/assets/layouts/<screen-name>.drawio を手動で直す運用にすれば、設計書として完成させられる。
そして、残念なところ
- レイアウト図(フルスクリーンショット)上の 「各画面項目の上に項番が重なって表示されない」
- フルスクリーンショットを下地にして項番は付与できているものの、項番が本来指し示すべき項目の位置に載らず、ズレた場所に描画されてしまう
- 検索結果0の場合のスクショがとれていない
この2点が残る状態だと、既存の画面設計書を“更新(保守)目的”で回すにはまだ早い。
既存設計書がある場合、今回効いている「文章面の正確な記述」はすでに満たせていることが多く、更新で辛いのはむしろ 画面レイアウト(スクショ/番号/配置)の追従なので、そこが安定しないと使い勝手が良くならない。
次はどうすべきか?
- 追加で欲しいスクショ(例:検索結果0、バリデーション)を Chat入力側にも明示して取り漏れを減らす
- レイアウト図の「項番を項目の上に重ねる」精度を上げるには、座標ベースで配置する仕組みに寄せるのが良さそう
- 例えば、HTMLから要素の位置情報を取得し、項番を重ねる加工を Playwright 側で行うなど
とはいえ、まだまだプロンプト側に改善余地があるので、ここも含めて詰めていきます。
最後まで読んでいただきありがとうございました!!
参考リンク(URL)
