tauri-mcp

tauri-mcp

Controls any built Tauri app's UI via WebDriver, enabling mouse/keyboard actions, DOM inspection, and screenshots.

Category
访问服务器

README

tauri-mcp

A generic MCP server that drives a built Tauri app's UI over WebDriver (tauri-driver + msedgedriver on Windows / WebKitWebDriver on Linux): launch the real app, then click, type, scroll, drag, read, and screenshot it like a human — or drop to raw JS when needed.

Not tied to any one project. Point it at any local Tauri app with projectDir or appPath. This server only knows how to drive a window; anything app-specific (reading an app's own database or config) belongs in a separate server of your own.

Tools

All tools are prefixed app_ and operate on a single running session (one app at a time).

Session

Tool What it does
app_launch Launch a built Tauri app under WebDriver. projectDir (or appPath) picks which app; TAURI_PROJECT_DIR is the fallback. Hard-errors if the window never renders (see Troubleshooting).
app_close Close the session and stop tauri-driver.
app_status Whether a session is running, and if so the binary + driver port.
app_force_cleanup Kill orphaned tauri-driver/msedgedriver and reset state, when a crashed run left things half-up.
app_window Resize / move / maximize / minimize / fullscreen the window; reports resulting size+position.
app_reload Reload the webview (resets front-end state; backend process keeps its state).

Acting (mouse / keyboard)

Tool What it does
app_click Click by CSS selector or text (visible text / accessible name). button left/right/middle, count 2 for double-click.
app_click_at Left/right/middle click at raw x,y viewport coordinates (canvas / native-drawn UI).
app_scroll Mouse-wheel scroll by a pixel delta (+down/-up, +right/-left); optional selector to scroll a specific pane.
app_type Type value into an input/textarea found by selector or text (placeholder/label); optional Enter.
app_press_key Raw keyboard: any key — literal chars, F1-F12, arrows, Home/End/PageUp/Down, and modifier chords (Ctrl+A, Ctrl+Shift+K).
app_hover Hover an element (by selector or text) to trigger tooltips / hover menus.
app_select Pick an option from a native <select> by optionText/optionValue/optionIndex.
app_drag Drag an element onto another (to) or by a pixel offset — sliders, range inputs, reordering, canvas handles.

Reading / observing

Tool What it does
app_snapshot Title + visible text + every visible interactive element (role, text, selector). The "what can I act on" view.
app_read One element's live state: text, current input value (DOM property, reflects controlled React inputs), tag, displayed/enabled, optional attribute.
app_wait_for Poll until a selector/text appears or disappears — for async loading, toasts, dialogs.
app_console_logs Browser console output (log/warn/error + uncaught exceptions) since launch.
app_screenshot PNG screenshot of the window, or of a single element (selector/text) for focused visual diffing.
app_list_windows / app_switch_window List/switch windows, for apps with more than one WebviewWindow.

Escape hatch

Tool What it does
app_execute_js Run arbitrary JavaScript in the window and return the result.

app_execute_js is unrestricted: it can read/write any DOM or JS state and invoke any Tauri backend command directly via await window.__TAURI_INTERNALS__.invoke("cmd_name", { arg }) (always present in Tauri v2, regardless of withGlobalTauri) — anything the app's own frontend can do, including commands with real side effects (writing config, filesystem, launching processes). No sandboxing beyond what the app's own command handlers enforce. It's also the workaround for OS-native dialogs (see below).

Targeting elements: prefer text

app_snapshot emits positional CSS selectors like div > div:nth-of-type(3) > button, which break the moment the DOM is restructured. Wherever a tool takes a target, prefer text (visible text or accessible name) — app_click({ text: "Browse" }) is how a human would say it and survives layout changes. exact: true requires an exact match; otherwise it tries exact text, then substring, then ARIA accessible name (covers icon-only buttons with aria-label).

Requirements

  • Node 24+ and npm install once in this folder.
  • tauri-driver: cargo install tauri-driver --locked.
  • Windows: Microsoft Edge WebDriver version-matched to your installed WebView2 Runtime (Settings → About Microsoft Edge WebView2, or HKLM\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}pv). A mismatched major version connects fine but silently never leaves about:blankapp_launch now detects this and errors. winget install Microsoft.EdgeDriver does not reliably match; download the exact version from https://msedgedriver.microsoft.com/<version>/edgedriver_win64.zip and drop it at ./bin/msedgedriver.exe (checked first) or set EDGEDRIVER_PATH.
  • The target app must already be built, and not with plain cargo build — a debug binary points at devUrl and only renders if a Vite dev server is up. Use cargo tauri build --debug --no-bundle (fast) or cargo tauri build --no-bundle (release). app_launch does not build for you.

When projectDir/appPath is omitted, app_launch uses the TAURI_PROJECT_DIR environment variable; if that is unset too, it returns a clear error. There is no built-in default project.

Run / verify

npm install
# point it at any built Tauri app:
TAURI_PROJECT_DIR=/path/to/tauri-project npm run verify-automation
# or:
TAURI_APP_PATH=/path/to/built/app npm run verify-automation

The verify script launches the app, snapshots it, clicks the first interactive element, screenshots, and closes.

Known limitation: OS-native dialogs

WebDriver can only see the webview DOM. Tauri file/folder pickers, message boxes, and other OS-native dialogs are not part of the DOM and can't be clicked through — a flow that opens one will stall. Workaround: skip the dialog and drive the backend directly with app_execute_js, e.g.

// instead of clicking a "Choose folder" button that opens a native picker:
return await window.__TAURI_INTERNALS__.invoke("set_output_dir", { path: "/some/folder" });

Troubleshooting

  • app_launch errors "window never rendered" — msedgedriver/WebView2 version mismatch, or a plain cargo build binary. See Requirements.
  • "a session is already running" after a crashapp_force_cleanup, then relaunch.
  • Selectors keep breaking — target by text instead (see above).

Register with Claude Code

Add it to an .mcp.json (project root, or ~/.claude.json for all projects), then restart Claude Code. Tools then appear as tauri:app_launch, etc.

{
  "mcpServers": {
    "tauri": {
      "command": "node",
      "args": ["--no-warnings", "/absolute/path/to/tauri-mcp/index.mjs"]
    }
  }
}

Or via the CLI:

claude mcp add tauri -- node --no-warnings /absolute/path/to/tauri-mcp/index.mjs

推荐服务器

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 模型以安全和受控的方式获取实时的网络信息。

官方
精选