AI エージェント向け marsdawn
marsdawn コマンドラインツールを呼び出す AI エージェントとスクリプトのためのリファレンスです。このページのすべての例は、現在のソースからビルドしたツールに対して実際に実行したものです。
Markdown ファイルを PDF に変換するには、marsdawn export notes.md --json を実行し、stdout から1つの JSON オブジェクトを読み取ってください。Mermaid 図とハイライトされたコードは、MarsDawn アプリと同じ方法でレンダリングされます。export にアプリは不要ですが、open には必要です。
できること
export:MarsDawn アプリと同じ書き出しエンジンで、1つの Markdown ファイルをページ分割された PDF にレンダリングします。ウインドウは開きません。open:1つ以上の Markdown ファイルを MarsDawn アプリで開き、人が確認できるようにします。各ファイルが移動すべき行を指定したり、ウインドウのサイドバーにフォルダを表示したりすることもできます。
できないこと
- stdin から Markdown を読み込みません。ファイルパスを渡してください。
- PDF を stdout に書き出しません。PDF は常にファイルとして書き出され、stdout には結果だけが出力されます。
--forceを指定しない限り、既存のファイルを置き換えません。--allow-remote-imagesを指定しない限りウェブから画像を読み込まず、指定した場合も https のみです。openは MarsDawn アプリがインストールされていないと動作せず、コード 3 で終了します。exportにアプリは不要です。アプリは Mac App Store で配信中です。- MarsDawn 1.0 は
openが指定した行にジャンプします。 - macOS でのみ動作します。
export
marsdawn export notes.md --json
notes.pdf を notes.md の隣に書き出します。オプション:
-o, --output <path>:PDF の書き出し先。デフォルトは入力パスの拡張子を.pdfにしたものです。--theme <dawn|classic|modern|vivid>:テーマのライトパレット。デフォルトは$MARSDAWN_THEME、それもなければdawnです。--paper <a4|letter>:用紙サイズ。デフォルトはa4です。--allow-remote-images:レンダリング時にウェブから https の画像を読み込みます。--force:出力ファイルが存在する場合に置き換えます。--json:stdout にテキストではなく1つの JSON オブジェクトを出力します。
marsdawn export notes.md -o out.pdf --theme classic --paper letter --force --json
成功、終了コード 0:
{"diagramErrors":[],"ok":true,"output":"/path/to/out.pdf","pages":1,"paper":"letter","theme":"classic"}
output:書き出された PDF の絶対パス。pages:ページ数。themeとpaper:実際に使われた値。diagramErrors:レンダリングに失敗した Mermaid 図につき1件のメッセージ。PDF はそれでも書き出されます。
open
marsdawn open notes.md --json
marsdawn open notes.md:120 --json
marsdawn open notes.md --line 120 --json
marsdawn open . --json
marsdawn open notes.md --folder . --background --json
path:lineは移動先の行を指定します。その後にコロンが続く場合、たとえばnotes.md:120:8の列部分は無視されます。存在するファイル名を丸ごと表す引数は常にそのファイル名として扱われるため、weird:12という名前のファイルはそのまま開きます。--line <n>は単一ファイルの行を指定します。それ自体がコロンと数字で終わるパスも含みます。ファイルは1つだけ指定できます。- 行番号は 1 から 999999999 までで、それ以外は使用方法のエラーになります。
- 行の指定は marsdawn 0.3.0 で追加されました。MarsDawn 1.0 はその行にジャンプしてファイルを開きます。
- フォルダを引数にすると、書類としてではなくウインドウのサイドバーに開きます。
marsdawn open .で現在のフォルダを表示し、--folder <path>はファイルと一緒に同じことをします。ウインドウのサイドバーに表示できるフォルダは1つです:2つ指定すると使用方法のエラーになり、--folderを2回使った場合も(同じフォルダでも)エラーです。同じフォルダを引数でもう一度指定した場合は1つとして扱います。フォルダには行がないため、フォルダに--lineを指定すると使用方法のエラーです。-aはありません:指定すると使用方法のエラーになり、--folderを案内します。 --backgroundは MarsDawn を前面に出さずに開きます。人が別の作業をしている間にファイルを開くエージェント向けです。JSON はどちらでも同じです。- フォルダと
--backgroundは marsdawn 0.5.1 で追加されました。
成功、終了コード 0:
{"app":"/Applications/MarsDawn.app","ok":true,"opened":[{"line":120,"path":"/path/to/notes.md"}]}
opened:渡された順に、ファイルごとの1つのオブジェクト。pathはファイルの絶対パス、lineは行が指定されたときだけ現れます。app:それらを開いた MarsDawn アプリのパス。
フォルダを指定した場合(marsdawn 0.5.1 以降)、終了コード 0:
{"app":"/Applications/MarsDawn.app","folder":{"path":"/path/to/project","requested":true},"ok":true,"opened":[{"path":"/path/to/project/notes.md"}]}
folder:フォルダを指定したときだけ現れます。pathはその絶対パスです。requestedは常にtrueです:marsdawn は MarsDawn にフォルダの表示を依頼しましたが、サイドバーに実際に表示されたかどうかは分かりません。アプリが先に人にアクセスの許可を求めることがあるためです。「完了した」ではなく「依頼した」と報告してください。--waitが 0 より大きく、MarsDawn が 1.0.2 以降の場合、待ち時間が終わるとfolderにstatusも入ります:attached、needsUser、declined、failed、attachedDifferentFolder、full、unavailable、unknownのいずれかです。needsUserのときだけwaitingFor(confirmationまたはfolderChoice)も入ります。--waitがない場合や、結果を返さないアプリでは、folderは{"path": …, "requested": true}のままです。--waitが 0〜30 の範囲外ならコード 64 で終了し、error: "wait_out_of_range"を返します。(marsdawn 0.5.3 以降)- フォルダだけを指定したとき、
openedは空です。
marsdawn 0.2.x では opened はパス文字列のリストでした。両方を扱う必要がある場合は marsdawn --version を確認してください。
Claude Code が編集したファイルを開く
オプトインの Claude Code フックです。Claude が Markdown ファイルを書き込んだり編集したりすると、そのファイルを MarsDawn でバックグラウンドで開きます。開くのはセッションごと、ファイルごとに一度だけです。頼んでいないウインドウは注意をそらすので、追加しない限り有効にならず、プロジェクトごとに追加します。シェルコマンドを実行するだけなので、モデルのトークンは使いません。
--background のために marsdawn 0.5.1 以降と、MarsDawn アプリが必要です。
次の内容をプロジェクトの .claude/hooks/marsdawn-open.sh として保存し、chmod +x で実行可能にします。
#!/bin/sh
# Claude Code PostToolUse hook: open a Markdown file Claude just wrote or edited in MarsDawn,
# in the background, once per file per session. Never blocks Claude: every path exits 0.
input=$(cat)
file=$(printf '%s' "$input" | /usr/bin/jq -r '.tool_input.file_path // empty' 2>/dev/null)
session=$(printf '%s' "$input" | /usr/bin/jq -r '.session_id // "unknown"' 2>/dev/null)
case "$file" in
*.md|*.markdown) ;;
*) exit 0 ;;
esac
[ -f "$file" ] || exit 0
# A hook runs with Claude Code's PATH, which may not include Homebrew's.
marsdawn=$(command -v marsdawn || { [ -x /opt/homebrew/bin/marsdawn ] && echo /opt/homebrew/bin/marsdawn; }) || exit 0
[ -n "$marsdawn" ] || exit 0
# One list per session, so a file opens once however often Claude edits it.
seen="${TMPDIR:-/tmp}/marsdawn-hook/$session"
mkdir -p "$(dirname "$seen")"
grep -qxF "$file" "$seen" 2>/dev/null && exit 0
echo "$file" >> "$seen"
"$marsdawn" open --background "$file" >/dev/null 2>&1 || true
exit 0
次に、プロジェクトの .claude/settings.json にフックを追加します。自分だけで使う場合は .claude/settings.local.json に追加します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/marsdawn-open.sh" }
]
}
]
}
}
- Claude の Write ツールと Edit ツールのあとに実行されます。
.mdまたは.markdownで終わらないファイルには何もしません。 - Claude が何度編集しても、各ファイルは Claude Code のセッションごとに一度だけ開きます。記録は
$TMPDIR/marsdawn-hook/にセッションごとに一つのファイルとして残るので、新しいセッションでは再び開きます。 --backgroundにより MarsDawn は前面に出ません。作業中のウインドウのフォーカスはそのままです。- Claude の邪魔はしません。どの経路でも終了コード 0 で終わり、marsdawn や MarsDawn アプリがインストールされていなければ何もしません。
- フックの入力は
/usr/bin/jqで読みます。これは macOS 26 に含まれていて、MarsDawn アプリも macOS 26 を必要とします。 - 無効にするには、設定ファイルからこの項目を削除します。
失敗時
--json を指定すると、失敗時は stdout に1つの JSON オブジェクトを出力し、対応するコードで終了します。
{"error":"output_exists","message":"/path/to/notes.pdf already exists. Pass --force to replace it.","ok":false}
2、input_not_found:入力が存在しない、フォルダである、または UTF-8 テキストでない。または--folderのパスが存在しないか、フォルダでない。3、app_not_installed:MarsDawn がインストールされていない。openのみがこれを返します。4、output_exists:出力ファイルが存在する。--forceを指定してください。5、export_failed:書き出し自体が失敗した。6、app_cannot_open_folders:この MarsDawn はまだフォルダを表示できないため、何も開かなかった。openのみがこれを返します。64:使用方法のエラー。未知のオプション、無効な値、範囲外の行、複数ファイルやフォルダに対する--lineの指定、複数のフォルダの指定、-aの指定など。この場合は、--jsonを指定していても stderr にテキストとして出力されます。
JSON Schema
各 --json 結果に対応する JSON Schema(draft 2020-12):
- export.v1.json: export 成功時
- open.v4.json: open 成功時、marsdawn 0.5.3 以降、フォルダの
statusとwaitingForを含む - open.v3.json: open 成功時、marsdawn 0.5.1〜0.5.2、サイドバーに表示するフォルダを含む
- error.v3.json: 失敗時、すべてのコマンド共通、marsdawn 0.7.1 以降、
input_too_large(コード 5)とskill_install_failed(コード 7)を追加 - error.v2.json: 失敗時、両方のコマンド共通、marsdawn 0.5.2〜0.7.0
- open.v2.json: open 成功時、marsdawn 0.3.0〜0.5.0
- open.v1.json: open 成功時、marsdawn 0.2.x(
openedがパスのリストだった頃) - error.v1.json: 失敗時、両方のコマンド共通、marsdawn 0.5.1 以前
環境変数
MARSDAWN_THEME:exportが、--themeが指定されないときに使うテーマ。未知の値はエラーにならずdawnにフォールバックします。
必要環境
- このツールは macOS 15 以降で動作します。Apple シリコンでは、Homebrew がビルド済みのボトルをインストールし、他に何も必要ありません。Intel Mac やソースから自分でビルドする場合は、Swift 6.2 以降が必要で、これは Xcode 26 以降に付属しています。
- MarsDawn アプリには macOS 26 以降が必要です。
インストール
Homebrew を使う場合。Apple シリコンでは、Xcode 不要でビルド済みのボトルを数秒でインストールします。Intel Mac では marsdawn をソースからコンパイルするため数分かかり、Xcode 26 以降が必要です。
brew tap redtear1115/tap && brew install marsdawn
marsdawn --version
または、ソースからビルドします。最初のビルドでは依存関係の取得とコンパイルが行われ、これも数分かかります。
git clone https://github.com/redtear1115/mars-dawn-kit.git
cd mars-dawn-kit
swift build -c release --product marsdawn
.build/release/marsdawn export notes.md --json
marsdawn --version は 0.3.0 のようなバージョン番号を表示し、コード 0 で終了します。
次に
- エージェントで MarsDawn のテーマを作る:エージェントとテーマを作る。