Tauri MCP Server
by moinsen-dev
README.md
# Tauri Plugin: Model Context Protocol (MCP)
A comprehensive Tauri plugin and MCP server that bridges AI agents (Claude Code, Cursor, Cline, etc.) with your Tauri desktop applications, enabling intelligent debugging, testing, and automation capabilities.
## Overview
The Model Context Protocol (MCP) is an open protocol that standardizes how AI assistants interact with external systems. This plugin implements MCP for Tauri applications, allowing AI agents to:
- **Debug visually** by taking screenshots and analyzing UI state
- **Automate testing** through simulated user interactions
- **Inspect application state** via DOM access and storage inspection
- **Execute JavaScript** in the application context for advanced debugging
- **Control windows** programmatically for multi-window testing scenarios
### Why Use This Plugin?
Traditional debugging requires manual reproduction of issues and visual inspection. With this MCP plugin, AI agents can:
1. **See what you see** - Take screenshots to understand visual bugs
2. **Do what you do** - Simulate clicks, typing, and navigation
3. **Know what's inside** - Access DOM, localStorage, and application state
4. **Fix autonomously** - Execute JavaScript to test fixes in real-time
This is particularly powerful for:
- **Debugging visual regressions** - AI can compare screenshots before/after changes
- **Automated UI testing** - Generate and execute test scenarios
- **Cross-platform validation** - Verify behavior across different OS windows
- **State inspection** - Diagnose issues by examining storage and DOM structure
## About This Project
This plugin is based on the original [tauri-plugin-mcp](https://github.com/P3GLEG/tauri-plugin-mcp) by P3GLEG, and has been **heavily modified and improved** with:
### Major Enhancements
- **Console & Error Tracking**: New tools for capturing console logs and exceptions
- **Comprehensive Documentation**:
- Complete Quick Start guide
- Tool Parameters Reference
- AI Agent Usage Guide with debugging workflows
- Detailed Development Workflow guide
- Common debugging patterns and best practices
- **Enhanced Developer Experience**:
- Pre-commit checklist
- Step-by-step guide for adding new tools
- Code templates for Rust and TypeScript
- Testing strategies and examples
- **Production-Ready**: Extensive troubleshooting guide and error handling
- **Better Organization**: Structured documentation with clear examples
### Attribution
Original work: [P3GLEG/tauri-plugin-mcp](https://github.com/P3GLEG/tauri-plugin-mcp)
License: MIT (see [LICENSE](LICENSE))
We're grateful to P3GLEG for creating the foundation of this plugin. This fork aims to provide a more comprehensive, production-ready solution with extensive documentation for both AI agents and human developers.
## 📚 Documentation
**New to MCP?** Start with our comprehensive guides:
- **[Quick Start Guide](docs/QUICK_START.md)** - Get running in 15 minutes
- **[Integration Guide](docs/INTEGRATION_GUIDE.md)** - Complete setup and configuration
- **[Testing Guide](docs/TESTING_GUIDE.md)** - Master AI-powered testing
- **[Docs Overview](docs/README.md)** - Documentation hub
**Below:** Quick reference for the main README. See the guides above for step-by-step instructions.
## Quick Start
Want to get started immediately? Here's the minimal setup:
```bash
# 1. Add to your Tauri app's Cargo.toml
tauri-plugin-mcp = { path = "../.tauri-plugin-mcp" }
# 2. Register in src-tauri/src/main.rs (debug builds only!)
#[cfg(debug_assertions)]
{
use tauri_plugin_mcp::PluginConfig;
builder = builder.plugin(tauri_plugin_mcp::init_with_config(
PluginConfig::new("YourApp".to_string())
.start_socket_server(true)
.socket_path("/tmp/tauri-mcp.sock") // macOS/Linux
));
}
# 3. Build the MCP server
cd .tauri-plugin-mcp/mcp-server-ts
pnpm install && pnpm build
# 4. Configure your AI agent (Claude Code/Cursor/Cline)
# Add to ~/.config/claude/claude_code_config.json:
{
"mcpServers": {
"tauri-mcp": {
"command": "node",
"args": ["/absolute/path/to/.tauri-plugin-mcp/mcp-server-ts/build/index.js"]
}
}
}
# 5. Start your Tauri app and test!
pnpm run tauri dev
```
Now AI agents can debug your app! See [Getting Started](#getting-started) for detailed setup.
## Available MCP Tools - Quick Reference
| Tool | Purpose | Common Use Case |
|------|---------|-----------------|
| **take_screenshot** | Capture window or element images | Visual regression testing, bug reporting |
| **get_dom** | Retrieve HTML structure | Debugging dynamic content, state inspection |
| **execute_js** | Run JavaScript in webview | State inspection, API calls, framework access |
| **get_element_position** | Find element coordinates | Preparing for mouse clicks, layout debugging |
| **inject_console_capture** | Enable console log collection | Capture console.log/error/warn messages |
| **get_console_logs** | Retrieve captured logs | Debugging runtime errors, log analysis |
| **inject_error_tracker** | Enable exception tracking | Capture unhandled errors, promise rejections |
| **get_exceptions** | Retrieve tracked errors | Understanding crash causes, error patterns |
| **local_storage_get** | Read localStorage item | Session debugging, auth token inspection |
| **local_storage_set** | Write localStorage item | Testing state persistence, setting up test data |
| **local_storage_remove** | Delete localStorage item | Cleanup, testing deletion flows |
| **local_storage_clear** | Clear all localStorage | Reset to clean state |
| **local_storage_get_all** | Retrieve all storage | Complete state inspection |
| **manage_window** | Control window properties | Multi-window testing, positioning, focus |
| **health_check** | Verify plugin connectivity | Connection diagnostics, startup verification |
| **ping** | Simple connectivity test | Basic health check |
See [Features](#features) for detailed documentation of each tool.
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ AI Agent (Claude/Cursor) │
│ (MCP Client via stdio/SSE) │
└───────────────────────────┬─────────────────────────────────┘
│
│ MCP Protocol
│ (JSON-RPC)
│
┌───────────────────────────▼─────────────────────────────────┐
│ MCP Server (TypeScript - Node.js) │
│ • Implements MCP protocol │
│ • Exposes tools to AI agents │
│ • Manages socket connection lifecycle │
└───────────────────────────┬─────────────────────────────────┘
│
│ IPC Socket or TCP
│ (JSON commands)
│
┌───────────────────────────▼─────────────────────────────────┐
│ Tauri Plugin (Rust - Socket Server) │
│ • Listens on Unix socket/Named pipe/TCP │
│ • Processes JSON commands │
│ • Executes Tauri API calls │
└───────────────────────────┬─────────────────────────────────┘
│
│ Tauri IPC
│
┌───────────────────────────▼─────────────────────────────────┐
│ Your Tauri Application │
│ • Frontend (React/Vue/Svelte/etc.) │
│ • Webview rendering │
│ • Application logic │
└─────────────────────────────────────────────────────────────┘
```
### Component Breakdown
#### 1. **Tauri Plugin (Rust)**
- **Socket Server** (`socket_server.rs`): Manages persistent connections via IPC or TCP
- **Tool Implementations** (`src/tools/*.rs`): Individual Rust modules for each capability
- **Tauri Integration**: Hooks into Tauri's window and webview APIs
#### 2. **MCP Server (TypeScript)**
- **Client Connection** (`client.ts`): Connects to the Tauri plugin's socket
- **Tool Registry** (`src/tools/*.ts`): Maps MCP tool calls to socket commands
- **Protocol Handler**: Implements MCP specification for AI agent communication
#### 3. **Communication Flow**
```
AI Request → MCP Server → Socket → Tauri Plugin → Tauri API → App
← ← ← ← ←
AI Response JSON Rust Handler Result Effect
```
## Features
### Window Interaction
#### Take Screenshot
Capture high-quality images of any Tauri window with pixel-perfect accuracy.
**Use Cases:**
- Visual regression testing
- Bug reporting with context
- UI state verification
- Automated documentation generation
**Capabilities:**
- Configure JPEG quality (1-100)
- Specify exact dimensions or use window size
- Target specific windows in multi-window apps
- Base64 or file output
**Example:** AI can take a screenshot, analyze the UI, and tell you "The submit button is misaligned 3px to the right."
#### Window Management
Full programmatic control over window lifecycle and properties.
**Capabilities:**
- Position: Set x, y coordinates
- Size: Resize width and height
- State: Minimize, maximize, restore, focus
- Multi-window: Target specific windows by label
- Visibility: Show, hide, bring to front
**Use Cases:**
- Multi-window testing scenarios
- Window positioning tests
- Focus management debugging
- Screen layout automation
#### DOM Access
Retrieve the complete HTML structure and content from any webview.
**Capabilities:**
- Full DOM tree extraction
- JavaScript evaluation context
- Element inspection
- Computed styles and properties (via JS execution)
**Use Cases:**
- Debugging dynamic content
- Validating data-binding
- Analyzing generated markup
- State inspection without DevTools
**Example:** AI can read the DOM, find a specific element by selector, and verify its content or attributes.
### User Input Simulation
#### Mouse Movement
Simulate realistic mouse interactions with pixel-perfect accuracy.
**Capabilities:**
- Click: Left, right, middle button clicks
- Double-click and triple-click
- Movement: Absolute and relative positioning
- Scrolling: Vertical and horizontal with delta control
- Hold and drag operations
**Use Cases:**
- Automated UI testing
- Click-through flow validation
- Hover state testing
- Drag-and-drop testing
**Example:** AI can click a button, verify the result via screenshot, and continue a multi-step workflow.
#### Text Input
Programmatically input text into focused elements with keyboard simulation.
**Capabilities:**
- Type into any focused input/textarea
- Simulate keyboard events
- Special characters and modifiers
- Paste large text blocks
**Use Cases:**
- Form filling automation
- Input validation testing
- Search functionality testing
- Text editor interaction
**Example:** AI can fill out a form, submit it, and verify the submission success.
#### Execute JavaScript
Run arbitrary JavaScript code directly in your application's webview context.
**Capabilities:**
- Full access to window scope
- Return values to the plugin
- Async/await support
- Error handling and reporting
**Use Cases:**
- Advanced state inspection
- Dynamic testing scenarios
- Direct API calls
- Framework-specific interactions (React state, Vue store, etc.)
**Example:** AI can execute `window.store.getState()` to inspect Redux state, or call application methods directly.
### Data & Storage
#### Local Storage Management
Complete CRUD operations on browser localStorage.
**Capabilities:**
- Get: Retrieve individual items or all entries
- Set: Add or update key-value pairs
- Remove: Delete specific keys
- Clear: Wipe all storage
**Use Cases:**
- State persistence testing
- Cache debugging
- User preferences inspection
- Session data validation
**Example:** AI can check localStorage for authentication tokens, verify expiration, and test refresh flows.
#### Ping
Simple connectivity test to verify the plugin is responsive.
**Use Cases:**
- Connection health monitoring
- Startup verification
- Debugging connection issues
- Integration testing
## Tool Parameters Reference
Detailed parameter specifications for each MCP tool:
### Screenshot Tools
#### take_screenshot
```typescript
{
quality?: number; // JPEG quality 1-100 (default: 90)
width?: number; // Target width in pixels (optional)
height?: number; // Target height in pixels (optional)
window_label?: string; // Target window (default: main window)
}
```
### DOM & Inspection Tools
#### get_dom
```typescript
{
window_label?: string; // Target window (default: main window)
}
```
#### get_element_position
```typescript
{
selector: string; // CSS selector (required)
window_label?: string; // Target window (default: main window)
}
```
#### execute_js
```typescript
{
script: string; // JavaScript code to execute (required)
window_label?: string; // Target window (default: main window)
}
```
### Console & Error Tracking
#### inject_console_capture
```typescript
{
window_label?: string; // Target window (default: main window)
}
```
#### get_console_logs
```typescript
{
level?: "log" | "warn" | "error" | "info" | "debug"; // Filter by level
since?: number; // Unix timestamp - only logs after this time
limit?: number; // Max number of logs to return
window_label?: string; // Target window
}
```
#### inject_error_tracker
```typescript
{
window_label?: string; // Target window (default: main window)
}
```
#### get_exceptions
```typescript
{
since?: number; // Unix timestamp - only errors after this time
limit?: number; // Max number of errors to return
window_label?: string; // Target window
}
```
### Storage Tools
#### local_storage_get
```typescript
{
key: string; // Storage key (required)
window_label?: string; // Target window
}
```
#### local_storage_set
```typescript
{
key: string; // Storage key (required)
value: string; // Value to store (required)
window_label?: string; // Target window
}
```
#### local_storage_remove
```typescript
{
key: string; // Storage key (required)
window_label?: string; // Target window
}
```
#### local_storage_clear
```typescript
{
window_label?: string; // Target window
}
```
#### local_storage_get_all
```typescript
{
window_label?: string; // Target window
}
```
### Window Management
#### manage_window
```typescript
{
action: "resize" | "move" | "focus" | "minimize" | "maximize" | "restore";
window_label?: string; // Target window (default: main window)
x?: number; // X position for move action
y?: number; // Y position for move action
width?: number; // Width for resize action
height?: number; // Height for resize action
}
```
### Diagnostics
#### health_check
```typescript
{} // No parameters required
```
#### ping
```typescript
{} // No parameters required
```
## Getting Started
### Prerequisites
- **Rust** (latest stable): For Tauri development
- **Node.js** 18+: For the MCP server
- **pnpm** (recommended) or npm: Package management
- **Tauri CLI**: `cargo install tauri-cli`
### Step 1: Build the Plugin
First, build both the Rust plugin and TypeScript MCP server:
```bash
# Install dependencies
pnpm install
# Build the Rust plugin and TypeScript server
pnpm run build && pnpm run build-plugin
```
This will:
1. Compile the Rust plugin (`tauri-plugin-mcp`)
2. Build the TypeScript MCP server (`mcp-server-ts/build/`)
### Step 2: Integrate into Your Tauri App
#### 2.1 Add Dependency
If you don't have a Tauri app yet, follow [Tauri's quickstart guide](https://v2.tauri.app/start/create-project/).
In your app's `src-tauri/Cargo.toml`, add the plugin dependency:
```toml
[dependencies]
tauri-plugin-mcp = { path = "../path/to/tauri-plugin-mcp" }
# Or from a git repository:
# tauri-plugin-mcp = { git = "https://github.com/yourusername/tauri-plugin-mcp" }
```
In your app's `package.json`, add the guest bindings:
```json
{
"dependencies": {
"tauri-plugin-mcp": "file:../path/to/tauri-plugin-mcp"
}
}
```
#### 2.2 Register the Plugin
**IMPORTANT SECURITY NOTE:** Only enable MCP in development builds. This plugin provides deep access to your application and should NEVER be included in production.
In your `src-tauri/src/main.rs` (or `lib.rs` for mobile):
```rust
use tauri_plugin_mcp;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
let mut builder = tauri::Builder::default();
// Only enable MCP in development builds
#[cfg(debug_assertions)]
{
use tauri_plugin_mcp::PluginConfig;
builder = builder.plugin(tauri_plugin_mcp::init_with_config(
PluginConfig::new("YourAppName".to_string()) // Must match your app's window name
.start_socket_server(true)
// Choose ONE connection mode:
// Option 1: IPC Socket (Default - Recommended)
.socket_path("/tmp/tauri-mcp.sock") // macOS/Linux
// .socket_path("\\\\.\\pipe\\tauri-mcp") // Windows
// Option 2: TCP Socket (Useful for Docker/Remote debugging)
// .tcp("127.0.0.1".to_string(), 4000)
));
log::info!("MCP plugin enabled for development");
}
builder
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```
**Configuration Options:**
- **`PluginConfig::new(app_name)`**: The application name used to identify windows (must match your `tauri.conf.json` title)
- **`.start_socket_server(true)`**: Enables the socket server (required)
- **`.socket_path(path)`**: IPC socket location (Unix socket on macOS/Linux, Named Pipe on Windows)
- **`.tcp(host, port)`**: TCP socket configuration (alternative to IPC)
**Platform-Specific Socket Paths:**
- **macOS/Linux**: `/tmp/tauri-mcp.sock` (or any path in `/tmp`)
- **Windows**: `\\\\.\\pipe\\tauri-mcp` (Named Pipe format)
### Step 3: Configure MCP Server for Your AI Agent
The MCP server acts as a bridge between AI agents (Claude Code, Cursor, Cline) and your Tauri application.
#### 3.1 Build the MCP Server
```bash
cd mcp-server-ts
pnpm install
pnpm build
```
This creates `mcp-server-ts/build/index.js`, the entry point for AI agents.
#### 3.2 Configure Your AI Agent
Add the MCP server to your AI agent's configuration file:
**For Claude Code** (`~/.config/claude/claude_code_config.json` or `claude_desktop_config.json`):
**For Cursor** (`.cursor/mcp-config.json`):
**For Cline** (VSCode settings):
```json
{
"mcpServers": {
"tauri-mcp": {
"command": "node",
"args": ["/absolute/path/to/tauri-plugin-mcp/mcp-server-ts/build/index.js"]
}
}
}
```
**Replace `/absolute/path/to/` with the actual path on your system.**
#### Configuration Modes
##### Mode 1: IPC Socket (Default - Recommended)
Best for local development with lowest overhead. Uses platform-specific inter-process communication.
**Default Configuration (no env vars needed):**
```json
{
"mcpServers": {
"tauri-mcp": {
"command": "node",
"args": ["/path/to/mcp-server-ts/build/index.js"]
}
}
}
```
**Custom Socket Path:**
```json
{
"mcpServers": {
"tauri-mcp": {
"command": "node",
"args": ["/path/to/mcp-server-ts/build/index.js"],
"env": {
"TAURI_MCP_IPC_PATH": "/custom/path/to/socket"
}
}
}
}
```
**Platform-specific defaults:**
- macOS/Linux: `/tmp/tauri-mcp.sock`
- Windows: `\\\\.\\pipe\\tauri-mcp`
##### Mode 2: TCP Socket
Use TCP when:
- Running Tauri app in Docker
- Remote debugging across network
- IPC socket permissions issues
- Testing from multiple machines
**Configuration:**
```json
{
"mcpServers": {
"tauri-mcp": {
"command": "node",
"args": ["/path/to/mcp-server-ts/build/index.js"],
"env": {
"TAURI_MCP_CONNECTION_TYPE": "tcp",
"TAURI_MCP_TCP_HOST": "127.0.0.1",
"TAURI_MCP_TCP_PORT": "4000"
}
}
}
}
```
**Corresponding Tauri plugin configuration:**
```rust
#[cfg(debug_assertions)]
{
builder = builder.plugin(tauri_plugin_mcp::init_with_config(
PluginConfig::new("YourApp".to_string())
.start_socket_server(true)
.tcp("127.0.0.1".to_string(), 4000) // Must match MCP server config
));
}
```
**Security Warning:** TCP sockets expose your application to network connections. Use `127.0.0.1` (localhost) to prevent external access. Never use `0.0.0.0` in production-like environments.
#### Environment Variables Reference
| Variable | Default | Description |
|----------|---------|-------------|
| `TAURI_MCP_CONNECTION_TYPE` | `ipc` | Connection mode: `ipc` or `tcp` |
| `TAURI_MCP_IPC_PATH` | Platform-specific | Custom IPC socket path |
| `TAURI_MCP_TCP_HOST` | `127.0.0.1` | TCP server host (TCP mode only) |
| `TAURI_MCP_TCP_PORT` | `3000` | TCP server port (TCP mode only) |
## How It Works: Communication Flow
Understanding the communication flow helps with debugging and extending the plugin.
### Request/Response Cycle
```
1. AI Agent sends MCP request
↓
2. MCP Server receives tool call (e.g., "take_screenshot")
↓
3. MCP Server constructs JSON command
{
"action": "take_screenshot",
"params": { "quality": 80 }
}
↓
4. Socket Client sends command to Socket Server (IPC or TCP)
↓
5. Socket Server (Rust) receives JSON command
↓
6. Router dispatches to appropriate tool handler
↓
7. Tool handler calls Tauri API
(e.g., window.screenshot())
↓
8. Result returned as JSON
{
"success": true,
"data": { "image": "base64..." }
}
↓
9. Socket Client receives response
↓
10. MCP Server formats response per MCP protocol
↓
11. AI Agent receives result
```
### Component Details
#### Socket Server (Rust - `socket_server.rs`)
**Responsibilities:**
- Creates and manages socket listeners (IPC or TCP)
- Accepts incoming connections with persistent support
- Deserializes JSON commands from clients
- Routes commands to appropriate tool handlers
- Serializes responses back to JSON
- Handles errors and connection lifecycle
**Key Features:**
- **Persistent Connections**: Supports multiple requests per connection
- **Concurrent Clients**: Handle multiple AI agents simultaneously
- **Error Recovery**: Graceful handling of malformed requests
- **Type Safety**: Strongly-typed command/response structures
**Implementation:**
```rust
// Simplified example
match command.action.as_str() {
"take_screenshot" => {
let params: ScreenshotParams = serde_json::from_value(command.params)?;
let result = tools::take_screenshot(&app, params).await?;
Ok(json!({ "success": true, "data": result }))
}
// ... other actions
}
```
#### Socket Client (TypeScript - `client.ts`)
**Responsibilities:**
- Establishes connection to socket (IPC or TCP)
- Sends JSON-serialized commands
- Awaits and deserializes responses
- Implements retry logic for connection failures
- Manages connection pooling/reuse
**Key Features:**
- **Promise-based API**: Async/await support
- **Automatic Reconnection**: Retry failed connections
- **Timeout Handling**: Prevent hung requests
- **Type Definitions**: TypeScript interfaces for all commands
**Implementation:**
```typescript
// Simplified example
async function sendCommand(action: string, params: any): Promise<any> {
const command = { action, params };
await socket.write(JSON.stringify(command) + '\n');
const response = await socket.readLine();
return JSON.parse(response);
}
```
#### MCP Server (TypeScript - `mcp-server-ts/`)
**Responsibilities:**
- Implements MCP protocol specification
- Registers available tools with descriptions
- Translates MCP tool calls to socket commands
- Formats responses according to MCP schema
- Handles stdio communication with AI agents
**Tool Registration Example:**
```typescript
server.registerTool({
name: "take_screenshot",
description: "Capture a screenshot of the Tauri window",
inputSchema: {
type: "object",
properties: {
quality: { type: "number", minimum: 1, maximum: 100 }
}
}
});
```
## Troubleshooting
### Diagnostic Steps
Before diving into specific issues, follow this diagnostic checklist:
1. **Verify Tauri app is running in debug mode**
```bash
pnpm run tauri dev
# Look for log: "MCP plugin enabled for development"
```
2. **Check socket file exists** (IPC mode only)
```bash
# macOS/Linux
ls -l /tmp/tauri-mcp.sock
# Windows PowerShell
Get-ChildItem \\.\pipe\ | Select-String tauri-mcp
```
3. **Test socket connectivity** (TCP mode only)
```bash
# macOS/Linux
nc -zv 127.0.0.1 4000
# Windows
Test-NetConnection -ComputerName 127.0.0.1 -Port 4000
```
4. **Check MCP server logs**
- AI agent logs usually show MCP server stdout/stderr
- Look for connection attempts and errors
### Common Issues
#### Issue 1: "Connection refused" or "ECONNREFUSED"
**Symptoms:** MCP server cannot connect to the Tauri plugin.
**Causes & Solutions:**
- **Tauri app not running**: Start your app with `pnpm run tauri dev`
- **Socket server disabled**: Verify `.start_socket_server(true)` in plugin config
- **Mismatched connection modes**: Ensure both MCP server and Tauri plugin use the same mode (IPC or TCP)
- **Port mismatch (TCP)**: Verify port numbers match exactly:
```rust
// Tauri: .tcp("127.0.0.1".to_string(), 4000)
// MCP Server env: TAURI_MCP_TCP_PORT=4000
```
**Debug commands:**
```bash
# Check if socket server is listening (TCP mode)
lsof -i :4000 # macOS/Linux
netstat -an | findstr :4000 # Windows
# Check Tauri app logs
# Look for: "Socket server started on..."
```
#### Issue 2: "Socket file not found" (IPC mode)
**Symptoms:** Error mentioning socket path doesn't exist.
**Causes & Solutions:**
- **Socket not created**: Tauri app may have failed to start the socket server
- Check Tauri logs for socket creation errors
- Verify path has write permissions (try `/tmp` on Unix)
- **Wrong socket path**: Ensure paths match exactly:
```rust
// Tauri
.socket_path("/tmp/tauri-mcp.sock")
```
```json
// MCP Server (if custom path)
"env": { "TAURI_MCP_IPC_PATH": "/tmp/tauri-mcp.sock" }
```
- **Path cleared on reboot**: `/tmp` may be cleared on system restart
- Restart your Tauri app to recreate the socket
**Workaround:** Switch to TCP mode which doesn't use file system.
#### Issue 3: "Permission denied" (IPC mode)
**Symptoms:** Socket file exists but cannot be accessed.
**Causes & Solutions:**
- **File permissions**: Check socket file permissions
```bash
ls -l /tmp/tauri-mcp.sock
# Should be readable/writable by your user
```
- **SELinux/AppArmor (Linux)**: Security modules may block socket access
```bash
# Temporary disable SELinux (for testing only)
sudo setenforce 0
```
- **Windows named pipe permissions**: Ensure correct pipe name format
```rust
.socket_path("\\\\.\\pipe\\tauri-mcp") // Correct format
```
**Workaround:** Use TCP mode to avoid file system permissions.
#### Issue 4: Connection drops after each request
**Symptoms:** Each tool call requires reconnection; slow responses.
**Causes & Solutions:**
- **Outdated plugin version**: Ensure you're using the latest version with persistent connection support
- **Short timeouts**: Increase client timeout settings
- **Server-side errors**: Check Tauri logs for panics or errors that might kill connections
**Fix:**
```bash
cd tauri-plugin-mcp
git pull
pnpm run build && pnpm run build-plugin
```
#### Issue 5: "Tool not found" or tool calls fail
**Symptoms:** AI agent says tool doesn't exist or returns errors.
**Causes & Solutions:**
- **MCP server not built**: Rebuild the MCP server
```bash
cd mcp-server-ts
pnpm build
```
- **Tool not registered**: Check `mcp-server-ts/src/tools/index.ts` includes the tool
- **Schema mismatch**: Ensure tool parameters match the expected schema
**Debug:**
```bash
# List available tools using MCP Inspector
cd mcp-server-ts
npx @modelcontextprotocol/inspector node build/index.js
# Click "List Tools" to see registered tools
```
#### Issue 6: Screenshots are black or empty
**Symptoms:** Screenshot tool returns blank or all-black images.
**Causes & Solutions:**
- **Wrong window name**: Application name must match window title
```rust
PluginConfig::new("ExactAppName".to_string()) // Must match tauri.conf.json
```
- **Window not focused/visible**: Ensure window is visible and not minimized
- **Webview not loaded**: Wait for app to fully load before taking screenshots
- **macOS permissions**: Grant screen recording permission to your terminal/IDE
- System Preferences → Security & Privacy → Screen Recording
#### Issue 7: JavaScript execution fails
**Symptoms:** `execute_js` tool returns errors or undefined.
**Causes & Solutions:**
- **Webview not ready**: Ensure DOM is loaded before executing JS
- **Syntax errors**: Validate JavaScript syntax
- **CSP restrictions**: Content Security Policy may block inline scripts
- **Return value serialization**: Ensure returned values are JSON-serializable
**Example:**
```typescript
// Bad: Returns DOM element (not serializable)
execute_js({ script: "document.getElementById('app')" })
// Good: Returns serializable data
execute_js({ script: "document.getElementById('app').textContent" })
```
### Testing Your Setup
#### Using MCP Inspector
The official MCP Inspector provides a GUI for testing your server:
```bash
cd mcp-server-ts
# IPC mode (default)
npx @modelcontextprotocol/inspector node build/index.js
# TCP mode
TAURI_MCP_CONNECTION_TYPE=tcp \
TAURI_MCP_TCP_HOST=127.0.0.1 \
TAURI_MCP_TCP_PORT=4000 \
npx @modelcontextprotocol/inspector node build/index.js
# Windows (TCP mode)
set TAURI_MCP_CONNECTION_TYPE=tcp&& set TAURI_MCP_TCP_HOST=127.0.0.1&& set TAURI_MCP_TCP_PORT=4000&& npx @modelcontextprotocol/inspector node build\index.js
```
The Inspector allows you to:
- List all available tools
- View tool schemas and descriptions
- Execute tools with custom parameters
- See real-time request/response logs
#### Manual Testing
Test the socket connection directly:
```bash
# Test TCP socket
echo '{"action":"ping","params":{}}' | nc 127.0.0.1 4000
# Test Unix socket (macOS/Linux)
echo '{"action":"ping","params":{}}' | nc -U /tmp/tauri-mcp.sock
```
Expected response:
```json
{"success":true,"data":"pong"}
```
### Getting Help
If you're still stuck after trying these solutions:
1. **Check logs**: Collect logs from both Tauri app and MCP server
2. **Minimal reproduction**: Create a minimal Tauri app that reproduces the issue
3. **Open an issue**: Include:
- Operating system and version
- Tauri version (`cargo tauri info`)
- Connection mode (IPC or TCP)
- Full error messages and stack traces
- Configuration files (plugin config and MCP server config)
## AI Agent Usage Guide
This section provides guidance for AI agents (like Claude Code, Cursor, Cline) on how to effectively use this plugin for debugging Tauri applications.
### Recommended Debugging Workflow
When debugging a Tauri application, follow this systematic approach:
#### 1. **Verify Connectivity**
Always start by verifying the plugin is accessible:
```typescript
// Step 1: Health check
await health_check({});
// Step 2: Ping test
await ping({});
```
**What to check:**
- Plugin is loaded and responsive
- Socket connection is working
- MCP server can communicate with Tauri app
#### 2. **Set Up Monitoring**
Before investigating issues, set up monitoring for runtime errors and logs:
```typescript
// Enable console log capture
await inject_console_capture({});
// Enable error tracking
await inject_error_tracker({});
```
**Why this matters:**
- Captures errors that occur during your investigation
- Logs provide context about what the app is doing
- Prevents missing important diagnostic information
#### 3. **Understand Visual State**
Take a screenshot to understand what the user is seeing:
```typescript
// Capture current visual state
const screenshot = await take_screenshot({ quality: 80 });
// Analyze the screenshot to understand:
// - Is the UI rendered correctly?
// - Are there visual errors?
// - Which elements are visible?
```
**Use screenshots for:**
- Visual regression detection
- Confirming UI state before/after actions
- Identifying layout issues
- Documenting bugs
#### 4. **Inspect DOM Structure**
Examine the HTML structure to understand the application state:
```typescript
// Get full DOM
const dom = await get_dom({});
// Or find specific elements
const buttonPos = await get_element_position({
selector: "button.submit"
});
```
**Look for:**
- Missing or unexpected elements
- Incorrect attributes or classes
- Dynamic content issues
- Framework-specific data attributes
#### 5. **Check Application State**
Inspect application state using JavaScript execution:
```typescript
// Check React state (if using React)
const state = await execute_js({
script: `
const app = document.getElementById('root');
const fiber = app._reactRootContainer?._internalRoot?.current;
// Return serializable state information
JSON.stringify({ /* state data */ });
`
});
// Check localStorage for session data
const storage = await local_storage_get_all({});
// Check specific configuration
const config = await execute_js({
script: "JSON.stringify(window.__APP_CONFIG__ || {})"
});
```
**Common state sources:**
- Redux store: `window.store?.getState()`
- Zustand: `window.useStore?.getState()`
- Vue store: `window.app?.$store?.state`
- Local/session storage
- Global configuration objects
#### 6. **Review Runtime Logs**
Check console logs and errors for diagnostic information:
```typescript
// Get recent error messages
const errors = await get_exceptions({
since: Date.now() - 60000, // Last minute
limit: 50
});
// Get console logs
const logs = await get_console_logs({
level: "error",
since: Date.now() - 60000
});
// Analyze patterns:
// - Are there recurring errors?
// - What was the sequence of events?
// - Are there unhandled promise rejections?
```
#### 7. **Form and Test Hypotheses**
Based on the information gathered, form hypotheses and test them:
```typescript
// Example: Testing if a specific function exists
const hasFunction = await execute_js({
script: "typeof window.myFunction === 'function'"
});
// Example: Testing if data loaded
const dataLoaded = await execute_js({
script: `
const data = window.myData;
JSON.stringify({
exists: !!data,
length: data?.length || 0,
isEmpty: !data || data.length === 0
});
`
});
// Example: Testing localStorage state
const authState = await local_storage_get({ key: "auth_token" });
```
### Best Practices for AI Agents
#### Do's
1. **Always verify connectivity first** - Use `health_check()` or `ping()` before attempting other operations
2. **Set up monitoring early** - Call `inject_console_capture()` and `inject_error_tracker()` at the start of debugging sessions
3. **Take screenshots before and after actions** - Document visual changes to understand impact
4. **Use execute_js for complex queries** - Batch multiple checks into a single JavaScript execution to reduce round trips
5. **Check logs after each significant action** - Use `get_console_logs()` and `get_exceptions()` to catch errors immediately
6. **Clean up test data** - Use `local_storage_clear()` or `local_storage_remove()` to reset state between tests
7. **Be specific with selectors** - Use precise CSS selectors in `get_element_position()` to avoid ambiguity
8. **Handle errors gracefully** - Wrap tool calls in try-catch and provide helpful context when operations fail
#### Don'ts
1. **Don't assume the plugin is always available** - Always verify connectivity, especially in new sessions
2. **Don't skip visual verification** - Screenshots provide critical context that logs cannot
3. **Don't execute untrusted code** - Only run JavaScript that you've verified is safe
4. **Don't ignore TypeScript types** - Use the parameter types defined in the Tool Parameters Reference
5. **Don't overwhelm with requests** - Batch operations when possible to reduce overhead
6. **Don't forget about multi-window apps** - Use `window_label` parameter to target specific windows
7. **Don't assume synchronous execution** - All operations are async; use await properly
8. **Don't leave monitoring enabled in production** - Console/error tracking is for debugging only
### Common Debugging Patterns
#### Pattern 1: Debugging a Form Submission Issue
```typescript
// 1. Verify form is visible
const screenshot = await take_screenshot({});
// 2. Check form state
const formData = await execute_js({
script: `
const form = document.querySelector('form');
const formData = new FormData(form);
const obj = {};
formData.forEach((value, key) => obj[key] = value);
JSON.stringify({
action: form.action,
method: form.method,
data: obj
});
`
});
// 3. Check for validation errors
const logs = await get_console_logs({ level: "error" });
// 4. Check network-related errors (if applicable)
const exceptions = await get_exceptions({});
```
#### Pattern 2: Debugging State Management Issues
```typescript
// 1. Inspect current state
const currentState = await execute_js({
script: "JSON.stringify(window.store?.getState() || {})"
});
// 2. Check localStorage for persisted state
const persistedState = await local_storage_get({ key: "redux_state" });
// 3. Compare expected vs actual
// 4. Check for state update errors in logs
const logs = await get_console_logs({ level: "warn" });
```
#### Pattern 3: Debugging Visual Rendering Issues
```typescript
// 1. Take screenshot
const screenshot = await take_screenshot({});
// 2. Get DOM to check element attributes
const dom = await get_dom({});
// 3. Check element positioning
const position = await get_element_position({
selector: ".problematic-element"
});
// 4. Check computed styles
const styles = await execute_js({
script: `
const el = document.querySelector('.problematic-element');
const styles = window.getComputedStyle(el);
JSON.stringify({
display: styles.display,
visibility: styles.visibility,
opacity: styles.opacity,
position: styles.position,
zIndex: styles.zIndex
});
`
});
```
#### Pattern 4: Debugging API Integration Issues
```typescript
// 1. Check for network errors in console
const logs = await get_console_logs({ level: "error" });
// 2. Check application state for API responses
const apiState = await execute_js({
script: `
JSON.stringify({
baseURL: window.API_BASE_URL,
lastResponse: window.__lastAPIResponse__,
pendingRequests: window.__pendingRequests__?.length || 0
});
`
});
// 3. Check localStorage for tokens
const authToken = await local_storage_get({ key: "auth_token" });
// 4. Verify token format and expiration
const tokenInfo = await execute_js({
script: `
try {
const token = localStorage.getItem('auth_token');
if (!token) throw new Error('No token');
const parts = token.split('.');
const payload = JSON.parse(atob(parts[1]));
JSON.stringify({
isExpired: payload.exp * 1000 < Date.now(),
expiresAt: new Date(payload.exp * 1000).toISOString()
});
} catch (e) {
JSON.stringify({ error: e.message });
}
`
});
```
### Error Handling for AI Agents
When tool calls fail, handle errors systematically:
```typescript
try {
const result = await some_tool({ params });
} catch (error) {
// 1. Check if it's a connectivity issue
try {
await ping({});
} catch (pingError) {
// Plugin is not accessible - inform user
// Suggest: Check if Tauri app is running
// Suggest: Verify socket configuration
return;
}
// 2. Check if it's a parameter validation issue
if (error.message.includes('validation')) {
// Review parameter types in Tool Parameters Reference
// Provide corrected parameters
}
// 3. Check if it's a window-specific issue
if (error.message.includes('window')) {
// Verify window_label is correct
// Check if window still exists
}
// 4. Provide helpful context to user
// Include: What you were trying to do
// Include: The specific error message
// Include: Suggested next steps
}
```
### Performance Tips
1. **Batch JavaScript execution:**
```typescript
// Good: Single execution
const allData = await execute_js({
script: `
JSON.stringify({
title: document.title,
url: location.href,
userCount: document.querySelectorAll('.user').length,
isLoggedIn: !!localStorage.getItem('auth_token')
});
`
});
// Bad: Multiple round trips
const title = await execute_js({ script: "document.title" });
const url = await execute_js({ script: "location.href" });
const userCount = await execute_js({ script: "document.querySelectorAll('.user').length" });
```
2. **Use appropriate screenshot quality:**
- Use `quality: 60-70` for quick checks
- Use `quality: 90-100` for detailed analysis
- Lower quality = faster transfer, smaller size
3. **Limit log retrieval:**
- Use `limit` parameter to avoid retrieving thousands of logs
- Use `since` parameter to get recent logs only
- Filter by `level` to focus on errors
4. **Cache DOM if analyzing multiple times:**
- Get DOM once and analyze it multiple times in your code
- Only fetch again if you've made changes to the app
## Usage Examples
### Example 1: Visual Regression Testing
Have AI agents automatically detect UI changes:
**Prompt to AI:**
> "Take a screenshot of the main window, then click the 'Theme' button and take another screenshot. Compare the two and tell me what changed visually."
**What happens:**
1. AI takes initial screenshot
2. AI simulates mouse click on theme button
3. AI takes second screenshot
4. AI analyzes both images and reports differences (colors, layout, etc.)
### Example 2: Automated Form Testing
Test form validation and submission:
**Prompt to AI:**
> "Fill out the registration form with invalid data and verify the error messages are displayed correctly."
**What happens:**
1. AI uses `text_input` to type into form fields
2. AI uses `mouse_movement` to click submit button
3. AI uses `take_screenshot` to capture error state
4. AI uses `get_dom` to verify error messages in DOM
5. AI reports whether validation works correctly
### Example 3: State Inspection
Debug application state without opening DevTools:
**Prompt to AI:**
> "Check the current Redux store state and tell me if the user is authenticated."
**What happens:**
1. AI uses `execute_js` to run: `window.store.getState()`
2. AI examines the returned state object
3. AI reports authentication status and related data
### Example 4: Multi-Window Testing
Test multi-window scenarios:
**Prompt to AI:**
> "Open the settings window, change the theme to dark, take a screenshot, then switch back to the main window and verify the theme changed there too."
**What happens:**
1. AI uses `window_manager` to focus settings window
2. AI interacts with theme controls
3. AI takes screenshot of settings window
4. AI switches to main window using `window_manager`
5. AI verifies theme consistency across windows
### Example 5: localStorage Debugging
Inspect and modify stored data:
**Prompt to AI:**
> "Check what's stored in localStorage and clear any expired session tokens."
**What happens:**
1. AI uses `local_storage_get_all` to retrieve all entries
2. AI examines token expiration dates
3. AI uses `local_storage_remove` to clear expired tokens
4. AI confirms cleanup was successful
## Security Considerations
### Development-Only Usage
**CRITICAL:** This plugin provides powerful access to your application and should **NEVER** be included in production builds.
Always wrap plugin registration in debug assertions:
```rust
#[cfg(debug_assertions)]
{
builder = builder.plugin(tauri_plugin_mcp::init_with_config(...));
}
```
### Why This Matters
The plugin allows:
- **Arbitrary JavaScript execution** in your webview
- **Full DOM access** including sensitive data
- **Screenshot capture** of potentially sensitive UI
- **Storage access** including tokens and credentials
- **Input simulation** that could trigger unintended actions
### Production Build Protection
Verify the plugin is excluded from production:
```bash
# Build for production
pnpm run tauri build
# Check the binary doesn't include MCP symbols (Linux/macOS)
nm -a ./target/release/myapp | grep -i mcp
# Should return nothing if properly excluded
# Or check Cargo features
cargo tree --features | grep mcp
```
### Network Security (TCP Mode)
When using TCP mode:
1. **Bind to localhost only**: Never use `0.0.0.0`
```rust
.tcp("127.0.0.1".to_string(), 4000) // Safe
.tcp("0.0.0.0".to_string(), 4000) // DANGEROUS
```
2. **Firewall protection**: Ensure firewall blocks external access to MCP port
```bash
# macOS - block external access
sudo pfctl -e
```
3. **Use IPC instead**: Prefer IPC sockets which can't be accessed remotely
### Data Exposure Risks
Be aware that AI agents can access:
- **User credentials** in localStorage/sessionStorage
- **API tokens** in application state
- **Personal data** displayed in the UI
- **Business logic** via JavaScript execution
**Mitigation:**
- Use the plugin only with trusted AI agents
- Review AI agent prompts before execution
- Clear sensitive data from development environments
- Use test accounts, not production credentials
## Advanced Topics
### Extending the Plugin
Add custom tools for your specific needs:
#### 1. Create Rust Tool Handler
Create `src/tools/custom_tool.rs`:
```rust
use tauri::{AppHandle, Runtime};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
pub struct CustomToolParams {
pub param1: String,
}
#[derive(Serialize)]
pub struct CustomToolResult {
pub result: String,
}
pub async fn custom_tool<R: Runtime>(
app: &AppHandle<R>,
params: CustomToolParams,
) -> Result<CustomToolResult, String> {
// Your custom logic here
Ok(CustomToolResult {
result: format!("Processed: {}", params.param1),
})
}
```
#### 2. Register in Router
In `src/tools/mod.rs`:
```rust
pub mod custom_tool;
// In the command router
match action {
"custom_tool" => {
let params = serde_json::from_value(command.params)?;
let result = custom_tool::custom_tool(&app, params).await?;
Ok(json!({ "success": true, "data": result }))
}
// ... other actions
}
```
#### 3. Add TypeScript Binding
In `mcp-server-ts/src/tools/custom_tool.ts`:
```typescript
export const customToolDefinition = {
name: "custom_tool",
description: "Your custom tool description",
inputSchema: {
type: "object",
properties: {
param1: {
type: "string",
description: "Parameter description"
}
},
required: ["param1"]
}
};
export async function customTool(params: { param1: string }) {
return await client.sendCommand("custom_tool", params);
}
```
#### 4. Register in MCP Server
In `mcp-server-ts/src/tools/index.ts`:
```typescript
import { customToolDefinition, customTool } from './custom_tool';
server.registerTool(customToolDefinition, customTool);
```
### Performance Optimization
#### Screenshot Compression
Reduce screenshot size for faster transmission:
```rust
PluginConfig::new("App".to_string())
.screenshot_quality(60) // Lower quality = smaller size
```
#### Connection Pooling
The plugin supports persistent connections. Ensure your client reuses connections:
```typescript
// Good: Reuse connection
const client = await createClient();
await client.sendCommand("ping", {});
await client.sendCommand("take_screenshot", {});
// Bad: New connection each time
await (await createClient()).sendCommand("ping", {});
await (await createClient()).sendCommand("take_screenshot", {});
```
#### Batch Operations
When possible, batch operations into single JavaScript executions:
```typescript
// Good: Single JS execution
execute_js({
script: `
const data = {
title: document.title,
url: window.location.href,
userCount: document.querySelectorAll('.user').length
};
JSON.stringify(data);
`
});
// Bad: Multiple roundtrips
execute_js({ script: "document.title" });
execute_js({ script: "window.location.href" });
execute_js({ script: "document.querySelectorAll('.user').length" });
```
### Cross-Platform Considerations
#### Window Name Matching
Different platforms may report window titles differently:
```rust
// macOS: Usually exact match
PluginConfig::new("MyApp".to_string())
// Windows: May include additional decorations
PluginConfig::new("MyApp - Window Name".to_string())
// Linux: Depends on window manager
// Test with: wmctrl -l
```
#### Socket Paths
Platform-specific default paths:
```rust
#[cfg(target_os = "macos")]
const DEFAULT_SOCKET: &str = "/tmp/tauri-mcp.sock";
#[cfg(target_os = "linux")]
const DEFAULT_SOCKET: &str = "/tmp/tauri-mcp.sock";
#[cfg(target_os = "windows")]
const DEFAULT_SOCKET: &str = "\\\\.\\pipe\\tauri-mcp";
```
#### Permission Differences
- **macOS**: Requires Screen Recording permission for screenshots
- **Windows**: May need admin rights for certain window operations
- **Linux**: Depends on X11/Wayland and window manager permissions
## Contributing
Contributions are welcome! Here's how to get started:
### Development Setup
```bash
# Clone the repository
git clone https://github.com/yourusername/tauri-plugin-mcp
cd tauri-plugin-mcp
# Install dependencies
pnpm install
# Build plugin and server
pnpm run build && pnpm run build-plugin
# Run tests
cargo test
cd mcp-server-ts && pnpm test
```
### Development Workflow
#### 1. Setting Up Your Development Environment
**Required Tools:**
- Rust toolchain (latest stable)
- Node.js 18+ and pnpm
- A Tauri test application
- MCP Inspector for testing: `npx @modelcontextprotocol/inspector`
**IDE Setup (Recommended):**
- **VS Code** with extensions:
- rust-analyzer
- Tauri
- ESLint
- Prettier
- **IntelliJ IDEA/RustRover** with Rust and Tauri plugins
#### 2. Making Changes
**For Rust Changes (Plugin Core):**
```bash
# 1. Make changes in src/
vim src/tools/my_tool.rs
# 2. Run format and lint
cargo fmt
cargo clippy
# 3. Build
cargo build
# 4. Test
cargo test
# 5. Test in real app
cd ../your-tauri-app
pnpm run tauri dev
```
**For TypeScript Changes (MCP Server):**
```bash
cd mcp-server-ts
# 1. Make changes in src/
vim src/tools/my_tool.ts
# 2. Run format and lint
pnpm run lint
pnpm run format
# 3. Build
pnpm build
# 4. Test
pnpm test
# 5. Test with MCP Inspector
npx @modelcontextprotocol/inspector node build/index.js
```
#### 3. Testing Your Changes
**Unit Tests:**
```bash
# Rust unit tests
cargo test
# TypeScript unit tests
cd mcp-server-ts && pnpm test
```
**Integration Testing:**
1. Start your Tauri test app with the plugin:
```bash
cd your-test-app
pnpm run tauri dev
```
2. Use MCP Inspector to test tools:
```bash
cd mcp-server-ts
npx @modelcontextprotocol/inspector node build/index.js
```
3. Or test with your AI agent (Claude Code, Cursor, Cline)
**Manual Socket Testing:**
```bash
# Test ping command
echo '{"action":"ping","params":{}}' | nc -U /tmp/tauri-mcp.sock
# Test health check
echo '{"action":"health_check","params":{}}' | nc -U /tmp/tauri-mcp.sock
```
#### 4. Debugging
**Rust Debugging:**
Enable verbose logging in your test app:
```rust
#[cfg(debug_assertions)]
{
env_logger::init(); // Add this
builder = builder.plugin(tauri_plugin_mcp::init_with_config(...));
}
```
Then run with:
```bash
RUST_LOG=debug pnpm run tauri dev
```
**TypeScript Debugging:**
Add debug logging in `mcp-server-ts/src/client.ts`:
```typescript
console.error('[MCP] Sending command:', command);
console.error('[MCP] Received response:', response);
```
Run with Node debugging:
```bash
node --inspect build/index.js
```
#### 5. Pre-Commit Checklist
- [ ] Code formatted (`cargo fmt`, `pnpm run format`)
- [ ] Lints pass (`cargo clippy`, `pnpm run lint`)
- [ ] Tests pass (`cargo test`, `pnpm test`)
- [ ] Changes tested in real Tauri app
- [ ] Documentation updated (README, doc comments)
- [ ] CHANGELOG.md updated (if applicable)
### Adding New Tools
Complete workflow for adding a new MCP tool:
#### Step 1: Plan the Tool
Define:
- **Purpose**: What problem does it solve?
- **Parameters**: What inputs does it need?
- **Return Type**: What data does it return?
- **Use Case**: When would AI agents use it?
Example:
```
Tool: get_network_requests
Purpose: Retrieve all network requests made by the app
Parameters: { since?: timestamp, filter?: regex }
Returns: Array of { url, method, status, headers, body, timing }
Use Case: Debugging API integration issues, analyzing performance
```
#### Step 2: Implement Rust Handler
Create `src/tools/my_tool.rs`:
```rust
use tauri::{AppHandle, Runtime};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
pub struct MyToolParams {
pub param1: String,
pub optional_param: Option<i32>,
}
#[derive(Serialize)]
pub struct MyToolResult {
pub data: String,
}
pub async fn my_tool<R: Runtime>(
app: &AppHandle<R>,
params: MyToolParams,
) -> Result<MyToolResult, String> {
// Implementation here
Ok(MyToolResult {
data: format!("Processed: {}", params.param1),
})
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_my_tool() {
// Add unit tests
}
}
```
#### Step 3: Register in Router
Add to `src/tools/mod.rs`:
```rust
pub mod my_tool;
// In the command router match statement
"my_tool" => {
let params = serde_json::from_value(command.params)?;
let result = my_tool::my_tool(&app, params).await?;
Ok(json!({ "success": true, "data": result }))
}
```
#### Step 4: Add TypeScript Binding
Create `mcp-server-ts/src/tools/my_tool.ts`:
```typescript
import { client } from './client';
export const myToolDefinition = {
name: "my_tool",
description: "Clear description of what the tool does",
inputSchema: {
type: "object",
properties: {
param1: {
type: "string",
description: "Parameter description"
},
optional_param: {
type: "number",
description: "Optional parameter"
}
},
required: ["param1"]
}
};
export async function myTool(params: {
param1: string;
optional_param?: number;
}) {
return await client.sendCommand("my_tool", params);
}
```
#### Step 5: Register in MCP Server
Add to `mcp-server-ts/src/tools/index.ts`:
```typescript
import { myToolDefinition, myTool } from './my_tool';
// In the setup function
server.registerTool(myToolDefinition, myTool);
```
#### Step 6: Write Tests
**Rust test:**
```rust
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_my_tool_success() {
// Test implementation
}
#[tokio::test]
async fn test_my_tool_validation() {
// Test error cases
}
}
```
**TypeScript test:**
```typescript
// mcp-server-ts/tests/my_tool.test.ts
import { myTool } from '../src/tools/my_tool';
describe('myTool', () => {
it('should process valid input', async () => {
// Test implementation
});
});
```
#### Step 7: Update Documentation
Add to README:
1. Add entry in Quick Reference table
2. Add to Tool Parameters Reference
3. Add example usage in Usage Examples section
### Code Style
- **Rust**: Follow `rustfmt` and `clippy` suggestions
- Run: `cargo fmt && cargo clippy`
- Fix all clippy warnings before committing
- **TypeScript**: Use ESLint and Prettier configurations
- Run: `pnpm run lint && pnpm run format`
- **Commits**: Use conventional commit format
- `feat:` for new features
- `fix:` for bug fixes
- `docs:` for documentation
- `refactor:` for code refactoring
- `test:` for adding tests
### Testing
```bash
# Rust tests
cargo test
# TypeScript tests
cd mcp-server-ts
pnpm test
# Integration tests with MCP Inspector
cd mcp-server-ts
npx @modelcontextprotocol/inspector node build/index.js
# Integration tests with real app
cd examples/test-app
pnpm run tauri dev
# Then test with your AI agent
```
### Common Development Tasks
**Rebuilding after changes:**
```bash
# Full rebuild
pnpm run build && pnpm run build-plugin
# Rust only
cargo build
# TypeScript only
cd mcp-server-ts && pnpm build
```
**Running with verbose logging:**
```bash
# Tauri app with debug logs
RUST_LOG=debug pnpm run tauri dev
# MCP server with debug logs
DEBUG=* node build/index.js
```
**Testing socket connectivity:**
```bash
# Check if socket exists
ls -l /tmp/tauri-mcp.sock
# Test with netcat
echo '{"action":"ping","params":{}}' | nc -U /tmp/tauri-mcp.sock
```
## License
[Specify your license here - e.g., MIT, Apache 2.0, etc.]
## Acknowledgments
- Built on [Tauri](https://tauri.app) - Secure desktop application framework
- Implements [Model Context Protocol](https://modelcontextprotocol.io) - Standard for AI-application integration
- Inspired by browser automation tools like Selenium and Playwright
## Resources
### Documentation
- **[Quick Start Guide](docs/QUICK_START.md)** - Get up and running in 15 minutes
- **[Integration Guide](docs/INTEGRATION_GUIDE.md)** - Comprehensive setup and troubleshooting
- **[Testing Guide](docs/TESTING_GUIDE.md)** - AI-powered testing scenarios and patterns
- **[Documentation Hub](docs/README.md)** - Complete documentation overview
### External Links
- **Tauri Documentation**: https://tauri.app/v2/
- **MCP Specification**: https://spec.modelcontextprotocol.io/
- **Original Plugin**: https://github.com/P3GLEG/tauri-plugin-mcp
- **Claude Code**: https://claude.com/claude-code
### Community
- **Issue Tracker**: [GitHub Issues](https://github.com/yourusername/tauri-plugin-mcp/issues)
- **Discussions**: [GitHub Discussions](https://github.com/yourusername/tauri-plugin-mcp/discussions)
- **Tauri Discord**: https://discord.gg/tauriThis server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues