mkd について
MKD は、決定、質問、レポート、表を一画面ずつ回答するブラウザー上のデッキにするローカル CLI です。構造化された入力が必要な AI との会話向けで、回答を実行用の JSON として返します。
主な機能
- 01インタラクティブデッキの4種類の項目
- 02決定オプションへの理由記載の必須化
- 03コピー&ペーストと待機型の回答フロー
- 04Orca と Claude Code の Artifact フロー
- 05デッキと結果を ~/.mkd/ に保存
活用シーン
- 01複数の決定に関するトレードオフの収集
- 02レポート各節への反応の収集
- 03表の行ごとの判定レビュー
- 04AI との会話へ構造化回答を返す
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ upex-galaxy/ agentic-user-skills --skill mkdインストール後、Claude Code で/mkdを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
cli/assets.d.tsindex.tsmarkdown.tsorca.test.tsorca.tsREADME.mdrender.test.tsrender.tsschema.tsserver.tscli/ui/app.cssapp.jsreferences/examples.mdschema.mdsetup.md詳細
MKD(mkd)— Make Decision
MKD は、AI が会話の途中で呼び出す、ローカルで動作する意思決定デッキ CLI です。ブラウザーのページを表示し、ユーザーはデッキ内の項目を 1画面ずつ(Slack のキャッチアップ形式で)確認します。項目には、根拠を示した選択肢のある意思決定、コントロール付きの質問、反応を求めるレポートのセクション、回答できるテーブルがあります。デフォルトのフローは、作業を止めないコピー&ペースト方式です。CLI はページを開いて終了し、ユーザーは好きなタイミングで回答して、結果の JSON をチャットに貼り付けます。この JSON が実行契約となり、AI はそこに書かれた内容をそのまま実行します。
このスキルにはインストール手順がありません。コンパイル済みバイナリはなく、PATH に追加するものもありません。AI は Bun を使い、スキルのディレクトリから CLI を実行します。すべての出力(レンダリングされたデッキ、結果、画像)は ~/.mkd/ 以下に保存され、現在の作業ディレクトリには保存されません。そのため、どのリポジトリ内で実行しても、そこに痕跡は一切残りません。
実行方法(インストール不要)
bun "<skill-dir>/cli/index.ts" <specPath> [--wait | --copy] [--no-open] [--port <n>] [--timeout <min>]
bun "<skill-dir>/cli/index.ts" <specPath> --artifact --title-prefix <session-name> # Claude Code only
<skill-dir> はこのスキルのインストールディレクトリです。
- プロジェクトレベル:
<repo>/.claude/skills/mkd - ユーザーレベル:
~/.claude/skills/mkd
Bun は TypeScript を直接実行するため、初回起動時の待ち時間はごくわずかです。Bun がない場合は、ユーザーにインストールするよう伝えてください(curl -fsSL https://bun.sh/install | bash)。Node で代用してはいけません。
AskUserQuestion とインラインの文章との使い分け
| 状況 | 使用するもの |
|---|---|
| 1~2個の選択肢から選ぶ場合、単一のはい/いいえの場合、単純な意思決定が3つ以内の場合 | AskUserQuestion |
| 意思決定のポイントが3つを超える場合、または背景情報と、文章で示されたトレードオフが必要な場合 | MKD |
| ユーザーが項目ごとに確認すべき、複数セクションにわたる長いレポート/計画 | MKD(report 項目) |
| 表形式のデータに対する行ごとの判断 | MKD(table 項目) |
| 正確な語句を基準に回答する必要がある場合 | MKD(ハイライトして引用) |
| 非対話型/CI/ブラウザーを使う人がいない場合 | どちらも使わず、プレーンテキストで出力 |
デッキのモデル
仕様は 項目のリストで、各項目が1画面にあたります。種類は4つです。
| 種類 | 画面に表示する内容 | 取得する回答 |
|---|---|---|
decision | 問題の説明(平易なプロダクトマネージャー向けの表現)+折りたたみ可能な背景情報の吹き出し+根拠を文章で示した選択肢+任意のカスタム選択肢+メモ | chosen キー(または "CUSTOM" + customText)、wasRecommended、note |
question | Markdown の内容+single/multi/toggle コントロール+自由入力テキスト | controlAnswer、text、quotes |
report | 反応を求めるレポートのセクション | text、quotes |
table | 行ごとに回答するテーブル(ポップオーバー式のコントロール+テキスト) | controlAnswer/text/quotes を持つ rows[] と、項目の note |
デッキの共通 UI は常に表示されます。導入画面(見出し+Markdown+統計タイル)、移動可能な進捗レール、← → キーによる移動、項目ごとの 今回はスキップ(スキップは後で決めるという意味で、却下ではありません)、サマリー画面、ライブフッター統計(回答済み/推奨に従った数/変更数/カスタム数/スキップ数)、ライト/ダークテーマ、localStorage によるデータ保持(タブを閉じてもデータは失われません)。
重要なルール — 根拠を示した選択肢(このツールの要点)
decision 項目を作成する場合:
- すべての選択肢に、文章による
justificationを付けてください。その選択肢で得られるもの(価値)と、そのためにかかるコストを示します。これがない選択肢はバリデーターに拒否されます(終了コード 2)。拒否に抗うのではなく、根拠を書いてください。 recommendedにできる選択肢は最大1つです。その根拠には、なぜそれを推奨するのかを明記してください(例:「…なので推奨します。」)。problemは、技術的な背景をすべて知らない人にも伝わる平易な言葉(プロダクトマネージャー向けの表現)で書きます。専門用語や内部のコードネームはcontextの吹き出しに入れ、現在の仕組みを説明してください。- ユーザーが知っておくべき実質的なトレードオフは、すべて文章で示してください。説明のない選択肢の列挙は、このツールがなくそうとしているまさにその失敗例です。
仕様スキーマの概要
{
"session": "audit-skills-alignment", // required — result echo + persistence key
"source": ".session/.../audit.md", // optional pointer to the source artifact
"title": "Catch-Up: audit decisions", // required
"intro": { // optional intro screen
"headline": "8 decisions await you",
"body": "Markdown, PM voice",
"stats": [{ "n": "115", "label": "verified findings" }]
},
"items": [
{
"id": "D1", "type": "decision", "title": "…",
"severity": "high", // optional: high | medium | low (chip)
"scope": "test-documentation", // optional (chip)
"problem": "Plain-language markdown problem statement",
"context": [{ "title": "How does X work today?", "body": "markdown" }],
"options": [
{ "key": "A", "label": "…", "justification": "Value + cost. **Recommended** because …", "recommended": true },
{ "key": "B", "label": "…", "justification": "Value + cost." }
],
"allowCustom": true // default true
},
{ "id": "Q1", "type": "question", "title": "…", "content": "markdown",
"controls": { "type": "single", "required": true, "options": [{ "value": "keep", "label": "Keep" }] },
"text": { "placeholder": "Why?" } },
{ "id": "R1", "type": "report", "title": "…", "content": "markdown section" },
{ "id": "T1", "type": "table", "title": "…", "content": "optional intro",
"table": { "columns": ["Test", "Rate"], "rows": [{ "id": "r1", "cells": ["a", "b"] }],
"rowControls": { "type": "single", "options": [ … ] } } }
]
}
すべてのフィールド、デフォルト値、検証ルールを含む完全な仕様 → references/schema.md。そのままコピーして使える仕様例 → references/examples.md。
どのフローを使うか:ハーネス別
実行しているハーネスに応じてフローを選んでください。アーティファクトモードには、Artifact、ArtifactData、ArtifactComments ツールが必要です。これらを利用できるのは Claude Code のみです(セッションが claude.ai にサインインしている場合に限ります)。CLI はこれらのツールを呼び出せないため、アーティファクトモードを自動的に選ぶことはありません。--artifact を指定してオプトインし、自分でページを公開してください。
| ハーネス | フロー | 方法 |
|---|---|---|
ツール一覧に Artifact ツールがある Claude Code | アーティファクトモード | --artifact --title-prefix <session-name> を指定してから、公開して監視します(以下の手順を参照) |
Artifact ツールがない Claude Code(claude.ai にサインインしていない場合:API キー、Bedrock、Vertex)、またはサブエージェント/プリントセッション(監視を保持できません) | その他のハーネス用フロー | 以下を参照 |
| OpenCode、Cursor、Codex、その他 | Orca 内の Orca タブ、そうでなければコピーモード。同じターン内の回答には --wait を使用 | 「どのフローが実行されるか:Orca か、それ以外か」を参照 |
Claude Code は、実行するシェルに CLAUDECODE=1 を設定します。これはハーネスを証明するものですが、このセッションが Artifact ツールを利用できることを示すものではありません。そのため、CLI はこれを検知すると stderr に1行のヒントを表示するだけで、通常のデフォルト設定を維持します。自分のツール一覧を確認してください。
正確な実行方法 — Claude Code(アーティファクトモード)
ユーザーは claude.ai のアーティファクト内で回答します。Claude に送信すると、Result JSON がアーティファクトのデータベースに保存され、Claude 宛てのコメントが投稿されるため、このセッションが再開します。localhost 上では何も実行されず、コピーするものもありません。
- 仕様を
~/.mkd/spec-<name>.jsonに書き込み、次に実行します。bun "<skill-dir>/cli/index.ts" ~/.mkd/spec-<name>.json --artifact --title-prefix <session-name>。 セッション名はListAgentsの1行目(「This session is …」)またはターミナルのタイトルです。CLI は仕様を検証し、~/.mkd/artifact-<name>.html(ページの断片:最初に<title>があり、doctype/html/head/body はありません)を書き込み、そのパスだけを stdout に出力し、何も開かずに終了コード 0 で終了します。stderr には回答が保存される db ドキュメントの名前が表示されます。終了コード 2 は、通常どおり仕様の不備を示します。 Artifactツールで公開します。file_pathには出力されたパス、icon(例:checklist)、1行のdescription、capabilities: {db: {}, comments: {}}を指定します。ユーザーにリンクを渡してください。- 監視状態を確認します。
ArtifactCommentsにaction: "watch"を指定し、urlを指定せずに呼び出すと、このセッションの監視一覧が表示されます。アーティファクトの行に auto-replies armed と表示されている必要があります。表示されていない場合は、そのアーティファクトのurlを指定してwatchを呼び出してください。監視が有効になっている場合のみ、送信によってこのセッションが再開します。その後、ターンを終了するか作業を続けてください。ポーリングはしないでください。 - 再開後(そのアーティファクト上で Claude 宛てにコメントが送信された場合)、
ArtifactDataにaction: "get"、collection: "results"、doc_idとして仕様のsessionを指定します(stderr に正確な ID が表示されます。db パスで使用できない文字は-に置き換えられます)。resultフィールドは Result JSON 文字列です。これを解析し、コピーモードと同じく実行契約として扱います。コメントスレッドに実行する内容を返信してから、解決済みにします(ArtifactCommentsのreply、続けてresolve)。 - デッキを修正するには、仕様を編集して同じコマンドを再実行し、同じ
file_pathで再公開します(または別の会話からアーティファクトのurlを渡します)。URL は変わらず、ブラウザーのストレージはアーティファクトに属するため、保存済みの回答も保持されます。
ページに「この表示では送信できません」と表示される場合(表示のみのアクセス権を持つユーザーなど、閲覧者に db の許可がない場合)、ユーザーは引き続き JSON をコピー を押して、チャットに貼り付けることができます。回答は保存されたものの通知に失敗した場合(「保存されましたが、Claude に通知されませんでした」)、ユーザーにチャットで知らせてもらい、手順 4 と同様に db ドキュメントを読み取ってください。アーティファクトモードでは画像の貼り付けは無効です(バイト列を保存するサーバーがありません)。
実行されるフロー:Orca またはそれ以外
CLI は何かを開く前に Orca を確認します。ORCA_TERMINAL_HANDLE が設定されている(プロセスが Orca 管理のターミナルで実行されている)か、orca status --json が到達可能なランタイムを報告すると、Orca が存在すると判定されます。実行ファイルは Orca 独自の orca-cli スキルと同じ方法で解決されます。まず ORCA_CLI_COMMAND、次に Orca の開発用チェックアウト内の orca-dev、次に管理対象ターミナルの外にある Linux では orca-ide(そこでは通常、単独の orca は GNOME のスクリーンリーダーです)、最後に orca の順です。確認に失敗した場合は「Orca なし」として扱われ、何も出力されません。
| 環境 | フラグ | 動作 |
|---|---|---|
| Orca なし | なし | コピー モード:レンダリングし、システムブラウザーを開いて、終了コード 0 で終了します。変更はありません。 |
| Orca なし | --wait | サーバーを起動し、システムブラウザーを開いて、送信されるまで処理をブロックします |
| Orca | なし | Orca フロー:サーバーを起動し、現在のワークツリーに紐づいたタブを開いて、ユーザーが Claude に送信 を押すまで処理をブロックし、結果の JSON を標準出力に出力します |
| Orca | --copy | コピー モードでシステムブラウザーを開き、終了コード 0 で終了します(従来のフロー) |
| 任意 | --no-open | 上記と同じモードですが、何も開きません。パスまたは URL は標準エラーに出力されます |
タブは --worktree path:<git toplevel of the cwd> で紐づけられるため、ユーザーが作業しているチェックアウト内から CLI を実行してください。orca tab create の後、CLI は orca tab list を読み取り、タブが存在し、loadError が null であることを確認します。タブを作成できない場合やページの読み込みに失敗した場合、CLI は作成したタブを閉じて、代わりにシステムブラウザーを開き、その旨を標準エラーに出力します。実行が終了すると(送信、タイムアウト、Ctrl-C、または SIGTERM)、開いたタブを閉じます。閉じる処理に失敗した場合は、そのタブが応答しないサーバーを指していることを標準エラーに出力します。
実行方法の詳細 — Orca 内(デフォルト)
CLI はユーザーが送信するまで処理をブロックするため、フォアグラウンドでは絶対に実行しないでください。フォアグラウンドで呼び出すと、エージェントのターンが最大 24 時間保持されます。
- 仕様を作成し、
~/.mkd/spec-<name>.jsonに保存します。 - ユーザーのチェックアウトディレクトリから、バックグラウンドで実行します。
- Claude Code:Bash ツールで
run_in_background: trueを指定して、bun "<skill-dir>/cli/index.ts" ~/.mkd/spec-<name>.jsonを実行します。プロセスが終了するとハーネスから通知されます。その後、標準出力を読み取ります。Orca 1.4.190 で測定済みです。 - OpenCode / Codex / Cursor(未検証:いずれも測定されていません):シェルでデタッチして起動し、出力先を
~/.mkd/にします。nohup bun "<skill-dir>/cli/index.ts" ~/.mkd/spec-<name>.json > ~/.mkd/stdout-<name>.json 2> ~/.mkd/stderr-<name>.log &。リダイレクトによってログは切り詰められるため、~/.mkd/stderr-<name>.logにresult written toが含まれたら、この実行の送信が完了しています。~/.mkd/result-<name>.json(標準出力と同じ Result)を読み取ります。ハーネスがバックグラウンドプロセスを維持できない場合は、--copyを渡し、以下のコピー モードの手順を使用します。
- Claude Code:Bash ツールで
- ユーザーに伝えます。デッキはこのターミナルの隣のタブで開いており、Send to Claude を押すと、コピーするものは何もなく回答が直接返されます。その後、ターンを終了するか、作業を続けます。
- プロセスの終了後、終了コードに従って対応します(
--waitの下の表を参照)。終了コード 0 の場合、標準出力には Result JSON が含まれます。コピー モードと同じく、これを実行契約として扱います。
安定したポート、回答の保持。 各デッキには 4747-4946 の範囲で専用のポートが割り当てられます。ポートは spec-<name>.json の <name>(なければ session)から導出されます。同じ仕様から回答途中のデッキを再度開くと、同じオリジンで開かれるため、保存済みの回答が復元されます。そのポートが使用中の場合、CLI は次に空いているポートにバインドし、元のポートに保存された回答は表示されないことを標準エラーに出力します。--port <n> を指定すると、導出されたポートを上書きできます。
同じデッキを同時に開くのは 1 つまで。 ブラウザーのストレージはオリジンとブラウザーエンジンごとに分かれています。同じデッキをシステムブラウザーと Orca のタブで開いた場合(または file:// ページとループバック経由で開いた場合)、回答はそれぞれ別々に保存され、統合されることはありません。CLI は各デッキを最後に開いた場所を ~/.mkd/opened-<name>.json に記録しており、今回の実行で別の場所に開く場合は標準エラーに警告を出します。その警告が表示されたら、どちらのコピーが有効かをユーザーに伝えてください。また、以前の ~/.mkd/result-<name>.json バックアップが存在する場合も通知します(次回の送信で上書きされます)。
実行方法の詳細 — Orca 以外でのデフォルト(コピー モード、非ブロッキング)
- 仕様を作成し、
~/.mkd/spec-<name>.jsonに保存します(このファイル名を使うと、ページは~/.mkd/deck-<name>.htmlに出力されます)。~/.mkd/の下に置くことで、リポジトリをクリーンな状態に保てます。 - 実行します:
bun "<skill-dir>/cli/index.ts" ~/.mkd/spec-<name>.json。CLI が検証を行い、自己完結型のページを生成してブラウザーを開き、直ちに終了コード 0 で終了します。標準出力には何も出力されません。 - ユーザーに伝えます。デッキはブラウザーで開いており、フッターの Copy JSON を押してチャットに貼り付けると回答が返されます。その後、ほかの作業を続けるか、ターンを終了します。ブロックしたり、ポーリングしたりしないでください。
- 貼り付けられた JSON が届いたら、解析して実行契約として扱います。
status: "skipped"の項目は「後で決める」という意味です(後で再度尋ね、拒否されたと決めつけないでください)。chosen: "CUSTOM"はcustomTextの記載どおりに実行することを意味します(内容に不整合があれば確認してください)。各項目のnoteは必ず確認します。
--wait(ブロッキング、同一ターンでの回答)
Orca の外では、AI が続行するために同じターン内で回答を本当に必要とする場合にのみ使用してください。Orca 内では、これがすでにデフォルトのフローです。
bun "<skill-dir>/cli/index.ts" <specPath> --waitはループバック経由でデッキを提供し(--port、デフォルト:4747-4946 の範囲でデッキに割り当てられた固定ポート。自動インクリメント)、実行ごとのx-mkd-token送信ゲートを設けて、ブラウザーからの送信を待機します(--timeout <min>、デフォルトは 1440=24 時間)。その後、Result JSON を標準出力(標準出力に出るのはこれのみ。バナーとエラーは標準エラー出力)に出力し、バックアップを~/.mkd/result-<name>.jsonに書き込みます。- 画像の貼り付け(クリップボード → 添付ファイル)が機能するのは、待機モード(
--waitまたは Orca フロー)のみです。imagesのエントリは~/.mkd/配下の絶対ファイルパスとして渡され、AI はReadで読み取れます。コピーモードでは、バイト列を保存するサーバーがないため、貼り付けは無効になります。
終了コードと不在時のプロトコル(--wait および Orca フロー):
| 終了コード | 意味 | AI の対応 |
|---|---|---|
| 0 | 送信済み — Result JSON が標準出力に出力されます | 解析して、同じターンを続行します |
| 1 | 送信なしでタイムアウト(または実行時エラー) | ユーザーは離席中です。エラーではありません — 待機中である旨を伝え、再起動を提案します |
| 2 | 不正な仕様(読み取り不能/検証失敗) | 報告されたパスの仕様を修正して、再実行します |
| 130 | Ctrl-C | ユーザーがキャンセルしました — 次に何をしたいか尋ねます |
| 143 | SIGTERM(ハーネスまたは何者かがバックグラウンドプロセスを終了させました) | 同じ仕様で再起動します。固定ポートにより、保存済みの回答が復元されます |
Result の読み取り
{
"session": "audit-skills-alignment",
"source": ".session/.../audit.md",
"submittedAt": "2026-08-21T…",
"stats": { "total": 8, "answered": 6, "skipped": 1, "recFollowed": 4, "overridden": 1, "custom": 1 },
"items": [
{ "id": "D1", "type": "decision", "title": "…", "status": "answered",
"chosen": "A", "chosenLabel": "…", "wasRecommended": true, "customText": "", "note": "…" },
{ "id": "Q1", "type": "question", "status": "answered", "controlAnswer": "keep", "text": "…", "quotes": ["…"] },
{ "id": "R1", "type": "report", "status": "skipped", "controlAnswer": null, "text": "", "quotes": [] },
{ "id": "T1", "type": "table", "status": "answered", "note": "", "quotes": [],
"rows": [{ "id": "r1", "controlAnswer": "fix", "text": "", "quotes": [] }] }
]
}
- アーティファクトモード:同じオブジェクトが、
results/<session>のresultフィールドに JSON 文字列として保存されます(sessionおよびsubmittedAtの隣)。コピーモードと同様に、ページが生成するもので、サーバーによる再構成は行われません。 controlAnswerはコントロールの種類に応じてデコードされます:single→string|null、multi→string[]、toggle→boolean。quotesは、ユーザーがその項目のコンテンツ(またはその行のセル)からハイライトした正確なフレーズです。textを解釈する際に重視してください。- すべての回答を紐付けるため、
items[].id(およびrows[].id)を、作成時に指定した ID に対応付けてください。
注意事項
- UI の表示要素は英語です(リポジトリ成果物のルール)。
title/problem/content/根拠説明には任意の言語を使用できるため、ユーザーの言語で記述してください。 - ページは Google Fonts から表示用フォントを読み込み、システムフォントへの完全なフォールバックも備えています。オフラインでも問題なく動作します。
- CLI は疎結合で、Bun の組み込み機能のみを使用し、外部依存関係はありません。
cli/README.mdを参照してください。