mcpField
L
LaTeX Look

LaTeX Look

ローカル
github.com生産性01 日前に更新

LaTeX Look について

LaTeX Look は、コンパイルしたページを視覚的に確認し、編集を検証するためのツールです。描画、ソース行の特定、ビルド比較を1回の呼び出しにまとめ、CLI と MCP サーバーも提供します。

主な機能

  1. 01LaTeX ページのコンパイルと描画
  2. 02PDF 座標からソース行を特定
  3. 03以前のビルドとのページ比較
  4. 04文書全体の変更を監査
  5. 05手動確認用 CLI

活用シーン

  1. 01コンパイルで検出できないレイアウト問題の確認
  2. 02ページ上の箇所に対応するソースの特定
  3. 03変更前後の差分による編集の検証

MCP 対応

MCP サーバーは MCP クライアントに `latex_look` ツールを公開します。ページ画像を返し、ページ選択、テキスト検索、座標からソースへの対応付け、比較、監査に対応します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"fangchenghao-latex-look": {
"command": "npx",
"args": [
"-y",
"@fffangchenghao/dsh-latex-look"
]
}
}
}
起動コマンドnpx -y @fffangchenghao/dsh-latex-look

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@fffangchenghao/dsh-latex-look0.4.0

ツール

1

掲載時のツール一覧 · 3 日前に更新

パラメーター型必須説明
dpinumberいいえレンダリング解像度。範囲は 50~300 です。デフォルトは 120 です。
filestringはいメインの .tex ファイルへのパス(絶対パス、または現在のディレクトリからの相対パス)。
pagenumberいいえレンダリングする PDF ページ(1 始まり)。`text` を使用する場合は省略してください。ページが自動的に特定されます。
textstringいいえページ上に表示される短い文字列(キャプション、見出し、固有のフレーズ)。対応するソースファイル:行番号とページを特定します。
auditbooleanいいえこのドキュメントの前回の監査と比較して、すべてのページのレイアウト退行を監査します。ページの内容が途中で終わる、低い位置から始まる、ほぼ空白になるといった問題のうち、今回の編集で生じたものだけを対象とします。キャプション、ヘッダー、間隔など、ページ全体に関わる種類の変更後に実行してください。
freshbooleanいいえビルドキャッシュを無視して最初からコンパイルします。キャッシュが古いと疑われる場合にのみ使用してください。
enginestringいいえauto | xelatex | lualatex | pdflatex | latexmk | tectonic。デフォルトは auto で、ドキュメントで使用されているものに応じて選択します。
pointXnumberいいえページ上の点の X 座標。pointY と併せて指定してください。前回の差分の bbox を渡すと、変更内容を確認できます。
pointYnumberいいえ同じ点の Y 座標。単位は PDF ポイントで、ページの左上隅を原点とします。
comparestringいいえ同じドキュメントの以前の PDF へのパス。ページとの差分を取り、変更前の画像をレンダリングします。
sequencestringいいえこの接頭辞で始まる番号付きラベルの読み順を確認します(例: '图' や 'Figure')。図がフロートになり、隣の項目がインラインのままだと順序が逆転し、読者がページをめくってから図 3-4 を図 3-3 より先に見ることになります。
auditBlankMmnumberいいえページ下部の空白が何 mm に達したら、監査で空白と判定するかを指定します。デフォルトは 30 です。

詳細

latex-look — エージェントに LaTeXを見て理解させる

npm tests license

英語 · 簡体字中国語

コンパイルできるのに見た目がおかしいページを、5回の編集で修正

左:エラーなしでコンパイルされています。右:読者が声に出して言える5つの指摘をもとに修正した後の状態です——「タイトルの周りの罫線を削除して」、「この表は格子状なので、booktabs形式の表にして」、「このリンクはページからはみ出している」、「図が大きすぎる」。examples/broken-layoutで実際にお試しください。

DeepSeek Harness プラグインで、追加するツールはlatex_lookの1つだけです。

.texソースしか読まないエージェントは、目が見えないのと同じです。文書はエラーなしでコンパイルできても、見た目がおかしいことがあります。latex_lookは文書をコンパイルしてページを画像としてレンダリングし、ページ上の任意の位置を正確なソース行に対応付け、直近の編集で変わった箇所を差分表示します。これらを1回の呼び出しで行います。

        ┌─────────────┐   latex_look   ┌──────────────┐
        │   agent     │ ─────────────► │  pdf → png   │
        │ (edits .tex)│                │  synctex     │
        └─────────────┘ ◄───────────── │  pixel diff  │
              ▲          image + line  └──────────────┘
              └─────────────── verification ───────────┘

ケーススタディを読む: 読者と同じように読む、215ページのLaTeX本 — 図163点、数式129点、きれいにコンパイルできる6種類の不具合。

ツール1つでよい理由

レンダリング、位置の特定、差分表示は、あくまで実装の詳細です。エージェントに必要なのは、人と同じように「このページを見て」という一貫した動詞です。latex_lookはコンパイル、レンダリング、対応付け、差分表示を1回の呼び出しで行うため、次のような流れになります。

look → diagnose → edit .tex → look again → confirm the change → report

インストール

Node ≥ 18、TeXエンジン(xelatex/lualatex/pdflatex/latexmkまたはtectonic)、synctex、ghostscriptが必要です。

このリポジトリ自体がバンドルです。package.jsonでdsh.bundle.patchを宣言し、cordis.patch.ymlで1行を挿入します。

git clone https://github.com/fangchenghao/latex-look

次に、現在のプロファイルにインストールします(Harnessのプラグインマネージャーから実行)。

plugin_manager  action: install_bundle  target: /absolute/path/to/latex-look

これによりlatex-lookの行が追加され、latex_lookツールが登録されます。インストール済みパッケージのソースを置き換えるには、新しいモジュール世代を読み込むためにHarnessを再起動する必要があります。

npmでは@fffangchenghao/dsh-latex-lookとして公開されているため、同じ行からレジストリより直接インストールすることもできます。

plugin_manager  action: install_bundle  target: @fffangchenghao/dsh-latex-look
更新

プラグインはバックグラウンドで1日1回レジストリを確認し、新しいリリースがある場合に限り、ツールの応答に1行追加します。何度も通知することはなく、オフラインのマシンには何も表示されません。アップグレードするには、同じバンドルを再度インストールします。

plugin_manager  action: install_bundle  target: @fffangchenghao/dsh-latex-look

稼働中のプロファイルではアップグレードがすぐに適用されます。core.mjsはindex.jsと異なりホットリロードされないため、Harnessは次回起動時にモジュール世代を再読み込みします。

チェックアウトからは、次のコマンドで直接確認できます。

npx latex-look --version
npx latex-look --check-update
リリース

v*タグを付けると、TeXとGhostscriptをインストールしたUbuntu上でテストスイートが実行され、タグとpackage.jsonが一致することを検証したうえで、npmに公開します。トークンはリポジトリシークレットのNPM_TOKENから取得します。

任意:ナレッジスキル

このツールはエージェントに目を与えます。SKILL.mdは、見たものに対処するためのLaTeXの知識を提供します。症状→原因→修正の手引きで、たとえば消したい罫線は、余計な\hlineではなく、通常は\pagestyle/fancyhdrが原因です。スキルのルートにコピーするか、シンボリックリンクを作成してください。

mkdir -p ~/.dsh/skills/latex-look
ln -sf "$PWD/SKILL.md" ~/.dsh/skills/latex-look/SKILL.md
CLI:人間向けおよびテスト向け
node bin/latex-look.mjs book.tex --page 37
node bin/latex-look.mjs book.tex --text "表3.1"
node bin/latex-look.mjs book.tex --page 12 --compare previous --json
node bin/latex-look.mjs book.tex --page 1 --audit   # what did the last edit break, anywhere?

CLIはプラグインと同じエンジンを実行し、Harnessを必要としません。そのため、何も再読み込みせずに変更を素早く確認できます。

Claude Desktop、Cursor、Codex 向け MCP サーバー

同じエンジンが Model Context Protocol サーバーとしても提供されるため、DSH を知らないクライアントでも利用できます。look() も、返される言葉も同じです。プラグインは Harness 向けの形式で、こちらは汎用形式です。

{
  "mcpServers": {
    "latex-look": {
      "command": "npx",
      "args": ["-y", "@fffangchenghao/dsh-latex-look", "mcp"]
    }
  }
}

これを claude_desktop_config.json(Claude Desktop)、~/.cursor/mcp.json (Cursor)、または ~/.codex/config.toml の TOML ブロックとして追加してください。

[mcp_servers.latex-look]
command = "npx"
args = ["-y", "@fffangchenghao/dsh-latex-look", "mcp"]

公開されるツールは latex_look の 1 つで、パラメーターはほかの場所と同じです。 file、page、text、pointX/pointY、compare、audit、sequence、dpi。 ページは画像コンテンツブロックとして返されるため、モデルはページそのものを確認できます。

必要なものは通常どおりです。TeX エンジンと、PATH 上の ghostscript です。

brew install --cask mactex-no-gui ghostscript     # macOS
sudo apt install texlive-xetex ghostscript        # Debian/Ubuntu
winget install MiKTeX.MiKTeX ArtifexSoftware.GhostScript   # Windows

Windows では PATH に何も追加する必要はありません。プラグインは gswin64c(Windows での Ghostscript の正式な名前)を要求し、見つからない場合は C:\Program Files\gs\gs*\bin に加えて、TeX Live、MiKTeX、TinyTeX のインストール ディレクトリを検索します。明示的に指定する場合は、PATH に C:\Program Files\gs\gs10.05.1\bin を追加すると、最初に使用されます。

何もアップロードされません。呼び出しのたびに、ディスク上にあるドキュメントをコンパイルします。

公式の MCP Registry に io.github.fangchenghao/latex-look として登録されているため、レジストリを検索するクライアントは名前でインストールできます。また、awesome-mcp-servers にも掲載されています。

テスト

クリーンなチェックアウトで 3 つのテストスイートを実行します。独自のフィクスチャを作成して実際のドキュメントをコンパイルするため、数分かかる場合があります。

node test/smoke.mjs           # unit level: problem parsing, PPM, raster diff, aux detection
node test/scenarios.mjs       # 52 end-to-end cases driven through index.js
node test/scenarios-deep.mjs  # 29 cases: multi-file papers, beamer, twocolumn, images,
                              #   engine switching, the build cache, hostile inputs
node test/book-scenarios.mjs  # 15 cases against a real 208-page book (164 .tex files)
node test/book-tasks.mjs      # 18 real editing tasks on the same book (see below)
LATEX_LOOK_BOOK=/pristine/copy node test/book-tasks.mjs   # point it at an unedited copy

書籍テストスイートには実際の書籍が必要です。指定しない限りスキップされます。

LATEX_LOOK_BOOK=/path/to/book node test/book-scenarios.mjs

次の 2 つのテストスイートが特に重要です。実際の書籍は、ルートファイルから \input{main} を経て \input{chap1} を読み込み、カスタム .sty、181 個の図、 用語集、fancyhdr によるページ装飾を含むためです。

book-scenarios は、その書籍で処理の仕組みを確認します。book-tasks は 依頼内容を確認します。各ケースはユーザーが実際に言いそうな一文で、書籍のコピーに適用した後、エージェントが確認する方法と同じように検証します。つまり、確認し、前回のビルドとの差分を取り、編集が作用する位置に変更があることを確かめます。

user saysmeasured
ヘッダーの横線を消して0.09%、bbox y=52 h=1(上部の細い帯)
ヘッダーの線が細すぎるので、2pt に太くして0.27%、bbox y=52 h=3
リンクの青色をなくして0.29%、目次ページ上の bbox
行間を少し広げて10.53%、208 → 248 ページ
表の行間を広げて9.07%
chap2 のまとめボックスが狭すぎるので、広げて7.39%
chap1 の図が小さすぎるので、大きくして10.57%
chap4 の図のグループは、揃えると右側が空いている8.81%
段落の先頭行は字下げしないで14.07%
余白が狭すぎる13.32%、208 → 226 ページ
本文のフォントサイズを 12pt にして11.63%、208 → 226 ページ
目次には章まで表示して2.19%、208 → 207 ページ

これらのケースでは、変更がどのように見えるかは一切検証しません。それを確認するのが画像の役割です。検証するのは、ビルドが成功したこと、差分があること、そしてそのバウンディングボックスが編集の作用する領域内にあることです。

どちらのエンドツーエンドテストスイートも、@deepseek-ai/dsh-tools(Harness 内だけに存在します)のみをスタブ化し、実際の引数で本物の execute を呼び出します。そのため、lib/core.mjs だけでなく、引数の処理とモデルが読む正確なテキストもテストできます。これは重要です。この方法で見つかったバグのいくつかは、フォーマット処理層にしか存在していませんでした。

SyncTeX が記録するページは、実際に配置されたページとは限りません

SyncTeX は、ボックスが組版されたページを記録します。TeX がフロートを次のページに移動すると、前のページ番号が記録されるため、text: "Version 0.5" は、206 ページに載る表に対して「205 ページ」と返すことがありました。しかし 205 ページは別の章です。ツールは現在、PDF 自体のテキストレイヤー(gs -sDEVICE=txtwrite、1 ページあたり約 0.12 秒)を確認し、前後 1 ページと 2 ページを検索します。SyncTeX の結果を上書きする場合は、その旨を示します。

2 枚ではなく 1 枚の画像

compare 呼び出しでは 3 枚の画像が書き出されますが、ユーザーに見せるのは images.sideBySide です。左に変更前のページ、右に変更後のページを配置した 1 枚の PNG です。ソースを読めない人にとって、別々の 2 ファイルを見比べて差分を見つけるのは、 作業の中で最も難しい部分です。

PNG の書き出しに依存関係は不要です。シグネチャ、IHDR、1 つの zlib IDAT、IEND があればよく、圧縮には node:zlib を使用します。合成にかかる時間は 140 dpi の A4 ページで約 0.3 秒で、比較対象がある場合にのみ実行されます。

パフォーマンス

編集の検証には、毎回実際にコンパイルする必要があり、これは避けられません。しかし、同じビルドのページを閲覧するたびにコンパイルする必要はありません。

操作208 ページの書籍
初回の閲覧(3 パス+用語集)約 17 秒
以降の閲覧(ソースに変更がない場合)約 0.2 秒

ドキュメント、そこから \input/\include されるすべてのファイル(3 階層まで)、その \includegraphics ファイル、および aux ファイルに変更がない場合(更新日時とサイズで判定)、ビルドを再利用します。失敗したビルドは再利用されません。キャッシュを使わない場合は fresh: true を渡します。

知っておくべき点が 2 つあります。

  • 変更前のスナップショットは呼び出しではなく、ビルドに紐付きます。 編集後、最初の閲覧でそのページの変更前の状態が記録されます。同じビルドでそれ以降に閲覧しても同じスナップショットが再利用されるため、エージェントが自分の編集箇所を 3 ページ調べる場合、2 ページ目と 3 ページ目でも差分を確認できます。(以前は最初の呼び出しで消費されていましたが、まさに逆の動作でした。)
  • ドキュメントごとに同時に実行できるビルドは 1 つです。 同じファイルのコンパイルを 2 つ同時に行うと、.aux/.toc を共有して互いに破損させます。208 ページの書籍で 2 つのプロセスを競合させたところ、一方がエラーメッセージも出さずに終了しました。現在はプロミスキューを使ってプロセス内で直列化し、所有者の PID を記録するロックファイルを使ってプロセス間でも直列化するため、強制終了された実行によってドキュメントがロックされたままになることはありません。

中間パスでの -draftmode は計測の結果、採用しませんでした。節約できる時間は約 2%にすぎず、時間がかかるのは PDF の書き出しではなく組版だからです。約 16 秒かかるのは TeX 自体です。

ツール

latex_look({
  "file": "book.tex",       // main .tex (required)
  "page": 37,               // optional, defaults to 1
  "text": "表3.1",          // optional: locate this string, show its page
  "pointX": 240,            // optional, with pointY: PDF points → source line
  "pointY": 610,
  "compare": "previous.pdf",// optional: diff against an earlier PDF
  "dpi": 200,               // optional, 50-300
  "engine": "xelatex",      // optional
  "maxPasses": 3,           // optional
  "timeoutSeconds": 300,    // optional
  "fresh": false,           // optional: ignore the build cache
  "audit": false,           // optional: whole-document layout audit vs the last run
  "auditBlankMm": 30        // optional: how deep a bottom hole must be to count,
  "sequence": "图"            // optional: check that numbered labels stay in reading order
})

以下を返します。

  • コンパイルの状態、パス数、ページ数、および構造化された problems。各項目には file、line、message が含まれます
  • warnings:LaTeX/Package/Class の警告に加え、見栄えの悪いページの一般的な原因となる Overfull/Underfull ボックス
  • toc:ドキュメントで \tableofcontents が宣言されているか、および実際に生成された項目数(目次が空の場合は成功ではなく問題として報告されます)。宣言は \input/\include をたどって検出するため、ルートファイルが \input{main} を読み込むだけの 1 行でも機能します
  • aux:実行された外部ツール(makeglossaries、makeindex、biber、bibtex)。ルートファイルのテキストではなく、最初のパスで生成された成果物に基づいて選択するため、\makeglossaries を読み込まれるプリアンブルに記述した複数ファイルのプロジェクトも処理できます
  • レンダリングされたページの PNG パス(画像リーダーに渡してください)
  • located:指定したテキストアンカーまたは点の { file, line, page }
  • diff:changedRatio と差分のバウンディングボックス(PDF ポイント単位)。pointX/pointY にそのまま渡せます
  • sequence:行頭から始まるラベルの読み取り順(「图 1-1」、「Figure 3.2」など)。浮動体は、ソース内で後に続くインラインオブジェクトより後に配置されるため、番号付きの連続項目の一部を浮動体にすると番号が逆順になります。これはページ単位の差分では決して検出できない唯一の不具合です
  • audit:ページ単位のレイアウト上の問題。書籍内の最も深い位置にあるテキストまで届かないページ、本文の開始位置が低いページ、ほぼ空白のページなどを、前回の監査が残したベースラインと比較します。そのため、newFindings には最新のビルドで発生した問題だけが含まれます。先に柱、罫線、ページ番号を検出して除外します。これを行わないと、ページ番号が「書籍内で最も低い位置にあるインク」とみなされ、すべてのページが問題のある状態に見えてしまいます

位置特定の仕組み

latex_look は -synctex=1 を指定してコンパイルするため、すべてのグリフにソース行へのリンクが付与されます。その後、次のように処理します。

  • 点 → ソース:synctex edit -o page:x:y:file.pdf
  • テキスト → ソース:.tex ソース内で文字列を検索し、該当箇所ごとに synctex view を実行してページと座標を取得します
  • 差分のバウンディングボックス → ソース:バウンディングボックスの中心を pointX/pointY として渡します

座標の単位は PDF ポイント(72ポイント=1インチ)で、原点はページの左上です。

既知の制限

  • page は PDF のページインデックスであり、ページに印刷された番号ではありません。 テスト用の書籍では両者に10の差があり(印刷番号130=インデックス140)、ローマ数字で番号が付けられた前付け部分では、その差はさらに異なります。PDF のページラベルがあればツール側で変換できますが、LaTeX は要求された場合にのみページラベルを書き込むため、ユーザーからページ番号を受け取ったエージェントは、まずレンダリングされたページでその番号を確認する必要があります。
  • SyncTeX が特定するのは、最も近いテキスト位置です。ページスタイル(\pagestyle{headings}、fancyhdr)によって描画される装飾的な罫線には、それ自体のグリフがないため、近くのテキスト位置が返されます。座標と LaTeX の知識を組み合わせてください。そのためのものが SKILL.md です。
  • 複数パスでの収束は .aux/.toc/.out/… のハッシュで確認します。\tableofcontents を含むドキュメントには2パス以上が必要で、目次が空の場合は latex_look が問題を報告します。
  • 複数ファイルの検出では、\input/\include を3階層までたどります。\import/\subfile、一般的でないカスタム .latexmkrc レシピ、\includeonly は認識されません。
  • エンジンが異なる場合にピクセル単位で一致させることはできません。TeX と Word の間でも、異なる2つの TeX エンジンの間でも、改行処理の仕組みが異なります。このツールが検証するのは、別の形式ではなく、使用しているエンジンの出力です。
  • ファイル名に % が含まれていると TeX エンジン自体がエラーになります(! Emergency stop.)。その場合、どのツールでも対処できません。ディレクトリ名に % が含まれていても問題ありません。
  • コンパイルに失敗して新しい PDF が書き出されなかった場合、ディスク上の古い PDF はレンダリングされず、差分も報告されません。代わりにツールがその旨を伝えます。そうしないと、変更のないファイルが「変更率0%」、つまり「編集が反映されていない」と表示されてしまうためです。
  • engine には、このツールのリストにあるエンジン(auto または既知の名前)だけを指定できます。検証されないまま spawn に渡されることはありません。
  • レンダリングされた PNG は TMPDIR/latex-look-<pid>/ に残ります。エージェントが呼び出しの戻り後にそれらを開くためです。このディレクトリを削除する処理はありません。
  • ビルドキャッシュが追跡するのは、ドキュメント、その \input/\include の対象、 \includegraphics のファイル、および補助ファイルです。変更された .sty や、リテラルな \input{...} ではなくマクロを通じて読み込まれたファイルは追跡されません。古いビルドの可能性がある場合は fresh: true を渡してください。
  • \tableofcontents を含むドキュメントで maxPasses: 1 を指定した場合、事前に .toc が存在しなければエラーとして、存在する場合は警告として報告されます。.toc ファイルは目次ページの組版後に書き込まれるため、1パスでは確実に空の目次ページが生成されます。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。