tex-mcp-web

tex-mcp-web

MCP server for agentic-first PDF review of LaTeX papers, enabling commenting, compiling, and visual inspection via Claude Code.

Category
访问服务器

README

tex-mcp-web

Agentic-first PDF review for LaTeX papers, with Claude Code as the author.

Hard fork of queelius/scholia v0.6.1 (MIT). Renamed and independently developed since.

You read the rendered PDF in your browser. You drop comments on paragraphs, sections, or the paper as a whole. Claude Code reads the queue (via MCP), edits the source, and replies with what changed. The PDF rebuilds in front of you. Repeat until done.

Why this exists

tex-mcp-web is deliberately not an editor, not an IDE, not an Overleaf clone. The agent (Claude Code) is already smarter at reading source, parsing LaTeX, grepping citations, and editing files than any tool we could build. So we don't try.

tex-mcp-web is a substrate for the agentic-first writing workflow:

  • A live PDF preview the human can watch and gesture at.
  • A comment queue anchored to PDF regions, sections, source ranges, or the paper as a whole.
  • A structured-error compile oracle the agent calls when it wants ground truth.

That's it. Three responsibilities. Anything that re-implements something the agent does well (file parsing, log analysis, semantic understanding) was deliberately removed.

Install

Requires Python 3.10+ and latexmk (or pdflatex/xelatex/lualatex/pandoc) on your PATH.

pip install "tex-mcp-web[mcp] @ git+https://github.com/MiiKiyoshi/tex-mcp-web"

The [mcp] extra adds the MCP server for Claude Code; [image] adds PDF-region rendering (pymupdf). Plain tex-mcp-web @ git+... installs the web viewer only.

Quick start

cd my-paper/
tex-mcp-web init --main main.tex   # writes .tex-mcp-web.yaml (main file, port)
tex-web                            # starts the daemon at http://localhost:8765

In the browser:

  • The PDF appears on the left, the comments sidebar on the right.
  • Select text in the PDF to anchor a comment to that region. SyncTeX maps the selection back to a source line range automatically.
  • Shift-click-drag to draw a rectangle around any region (figures, equations, whitespace) where text selection doesn't reach. Same pdf_region anchor; the agent can render exactly that region with image(comment_id=...).
  • Suggest a rewrite alongside any comment: the compose dialog has an optional {old, new} block. When you select text first, "old" pre-fills with the selected text, so you only type the replacement. The agent gets a structured edit it can apply directly.
  • "+ Note" in the top bar for a paper-level comment ("the abstract is too long").
  • Sections tab is the table of contents: numbered headings, click to jump, "+ comment" for section-level comments.
  • Compile tab lists compile errors and warnings; tab badges carry the open-comment and error/warning counts.
  • Reply / Resolve / Dismiss are inline forms in each comment, not modals.
  • Keyboard navigation: j / k step through comments, r opens a reply form, R opens resolve, d opens dismiss, Esc cancels, \ collapses the sidebar.
  • Ctrl/Cmd + wheel zooms the PDF around the cursor.

The Claude Code workflow

Register the MCP server once, globally:

claude mcp add --scope user tex-mcp -- tex-mcp

The server locates .tex-mcp-web.yaml by searching upward from Claude Code's working directory, so the same registration serves every paper: open Claude Code in a paper directory and the tools point at that paper.

This exposes 7 tools:

Tool What it does
paper(include_comments=True) Paper state in one call: sections (with line ranges), the comments queue, last-compile cache, main-file paths.
compile() Recompile and return structured errors with source context.
comment(action, ...) add / reply / resolve / dismiss / delete. Optional suggestion={"old", "new"} on add.
image(...) Render PDF region as PNG. Modes: page=N, page+bbox, source="file:lstart-lend", comment_id="c-...".
section(name) Deep-dive: source slice + rendered image + scoped comments for one section in one call.
audit(focus=...) Workflow primer for agent-initiated review. Returns guidance; the agent then files comments back as author="claude".
goto(target) Scroll the running viewer to a section / page / line / label.

When a compile finishes, the WebSocket broadcasts {"type": "compiled", ..., "pages_changed": [3, 7]} so the agent can verify only the pages that actually shifted, not re-render the whole document.

Notice what's absent: there's no tex-mcp-web_labels(), no tex-mcp-web_citations(), no tex-mcp-web_environments(). Use Grep. The agent is better at it than we are.

Visual review is the killer mode of image. Claude is multimodal; pure text won't tell it whether a figure caption attaches to the right figure or whether an equation rendered correctly. The comment_id mode is the fast path: human draws a rectangle around a figure, files the comment, agent renders that region, sees what the human pointed at, fixes the LaTeX.

Active review runs the loop in either direction:

You:    [drop 8 comments on the PDF; for "rephrase X" comments, fill
         in the suggested rewrite (agent applies it directly)]
        "Process the open comments."

Claude: paper()                           # see comments + sections
        for each: Read/Edit source; if suggestion present, apply it
        comment(action="resolve", id=..., summary="...")
        compile()                         # verify build

You:    [PDF rebuilds; reply / dismiss as needed]

You:    "Audit my methods section for notation drift."

Claude: audit(focus="math")               # guidance primer
        Read paper.tex; image() to inspect rendering
        comment(action="add", author="claude",
                        anchor=..., text="...", suggestion=...)
        # filed back into the queue, distinct visual treatment

Comment anchors

Four kinds, with different staleness behavior:

Anchor Use when Staleness handling
pdf_region Reading the PDF and pointing at a paragraph. SyncTeX resolves to source; a content snippet is captured; if Claude rewrites that region, the snippet match fails and the comment is flagged STALE.
section "Expand the methods section." Resolved by section title or \label{...}. Stale only if the section is removed or renamed.
source_range When the agent already knows the lines (most common from MCP). Snippet-matched, like pdf_region.
paper Global note about the paper. Never stale.

CLI

tex-mcp-web                 # serve (default)
tex-mcp-web init            # scaffold .tex-mcp-web.yaml
tex-mcp-web config          # print .tex-mcp-web.yaml
tex-mcp-web config port 9000   # set a value (main/port/compiler/watch/ignore/page_limit)
tex-mcp-web compile         # one-shot compile, structured errors
tex-mcp-web goto "Methods"  # tell the running viewer to scroll
tex-web                     # alias for `tex-mcp-web serve`
tex-mcp                     # run the MCP server (stdio)

That's the whole CLI. Comment management lives in the browser (for humans) and in the MCP tools (for the agent). There is no tex-mcp-web comment add from the shell because nobody types that.

What changed in v0.6.0 (active review)

The framing shifted from "human reviews; agent dispatches" to "review goes both ways":

  • Suggested rewrites. Comments now optionally carry a structured {old, new} block. The agent applies the rewrite directly instead of parsing prose. Browser pre-fills "old" with the selected PDF text so the human only types the replacement.
  • audit(focus=...) primes agent-initiated review. The agent reads the paper, files findings back as author="claude" comments, and the human steps through them.
  • Refactor: anchors resolve themselves. The dispatch that used to live in three switch statements (server._resolve_anchor, imaging.resolve_image_target, staleness check) is now methods on each anchor type. Adding a new anchor kind is a 30-line addition to one file.

What changed in v0.5.x

Aggressive simplification with the agentic-first frame:

  • Dropped the CLI comment surface entirely. The agent and the browser are the only sane places to manage comments.
  • Dropped tags, reopen, the Errors tab. Tags were noise, reopen was Github-imitation, the Errors tab duplicated information the topbar already shows.
  • Dropped labels / citations / inputs from paper(). Use Grep.
  • Folded comments into paper(include_comments=True) for one-call orientation.
  • Inline reply / resolve / dismiss forms in the viewer, not prompt() dialogs.
  • Compile lock prevents the watcher and compile() from racing.
  • Visual review via image() with four modes (page, page+bbox, source range, comment id). Shift-click-drag selects arbitrary rectangles for figures.

Configuration

.tex-mcp-web.yaml:

main: paper.tex
watch: ["*.tex", "*.bib", "*.md"]
ignore: ["*_backup.tex"]
compiler: auto       # auto | latexmk | pdflatex | xelatex | lualatex | pandoc
port: 8765

Comments live in .tex-mcp-web/comments.json. git add it to keep your review history with the paper.

License

MIT. See LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选