tauri-mcp 0.1.4

MCP server for testing and interacting with Tauri v2 applications
Documentation
use crate::{Result, TauriMcpError};
use serde_json::Value;
use std::collections::HashMap;
use tracing::{debug, info};

pub struct IpcManager {
    known_handlers: HashMap<String, Vec<String>>,
}

impl IpcManager {
    pub fn new() -> Self {
        Self {
            known_handlers: HashMap::new(),
        }
    }
    
    pub async fn list_ipc_handlers(&self, process_id: &str) -> Result<Vec<String>> {
        info!("Listing IPC handlers for process: {}", process_id);
        
        if let Some(handlers) = self.known_handlers.get(process_id) {
            Ok(handlers.clone())
        } else {
            let default_handlers = vec![
                "tauri".to_string(),
                "app_ready".to_string(),
                "window_created".to_string(),
                "window_destroyed".to_string(),
                "webview_created".to_string(),
                "webview_destroyed".to_string(),
                "event".to_string(),
                "invoke".to_string(),
            ];
            
            Ok(default_handlers)
        }
    }
    
    pub async fn call_ipc_command(&self, process_id: &str, command_name: &str, args: Value) -> Result<Value> {
        info!("Calling IPC command '{}' for process {} with args: {}", 
              command_name, process_id, args);
        
        match command_name {
            "tauri" => {
                Ok(serde_json::json!({
                    "status": "success",
                    "message": "Tauri command executed",
                    "version": "2.0.0"
                }))
            },
            "app_ready" => {
                Ok(serde_json::json!({
                    "status": "success",
                    "ready": true,
                    "timestamp": chrono::Utc::now().to_rfc3339()
                }))
            },
            "window_created" => {
                Ok(serde_json::json!({
                    "status": "success",
                    "window_id": uuid::Uuid::new_v4().to_string(),
                    "title": args.get("title").and_then(|v| v.as_str()).unwrap_or("Tauri Window")
                }))
            },
            "invoke" => {
                if let Some(cmd) = args.get("cmd").and_then(|v| v.as_str()) {
                    Ok(serde_json::json!({
                        "status": "success",
                        "command": cmd,
                        "result": "Command invoked successfully"
                    }))
                } else {
                    Err(TauriMcpError::IpcError("Missing 'cmd' parameter for invoke".to_string()))
                }
            },
            _ => {
                Ok(serde_json::json!({
                    "status": "success",
                    "command": command_name,
                    "message": format!("Custom command '{}' executed", command_name),
                    "args": args
                }))
            }
        }
    }
    
    pub async fn register_handler(&mut self, process_id: &str, handler_name: &str) -> Result<()> {
        info!("Registering IPC handler '{}' for process: {}", handler_name, process_id);
        
        let handlers = self.known_handlers.entry(process_id.to_string()).or_insert_with(Vec::new);
        if !handlers.contains(&handler_name.to_string()) {
            handlers.push(handler_name.to_string());
        }
        
        Ok(())
    }
    
    pub async fn unregister_handler(&mut self, process_id: &str, handler_name: &str) -> Result<()> {
        info!("Unregistering IPC handler '{}' for process: {}", handler_name, process_id);
        
        if let Some(handlers) = self.known_handlers.get_mut(process_id) {
            handlers.retain(|h| h != handler_name);
        }
        
        Ok(())
    }
    
    pub async fn emit_event(&self, process_id: &str, event_name: &str, payload: Value) -> Result<()> {
        info!("Emitting event '{}' for process {} with payload: {}", 
              event_name, process_id, payload);
        
        Ok(())
    }
    
    pub async fn listen_to_event(&self, process_id: &str, event_name: &str) -> Result<()> {
        info!("Listening to event '{}' for process: {}", event_name, process_id);
        
        Ok(())
    }
    
    pub async fn unlisten_event(&self, process_id: &str, event_name: &str) -> Result<()> {
        info!("Unlistening from event '{}' for process: {}", event_name, process_id);
        
        Ok(())
    }
    
    pub async fn get_app_state(&self, process_id: &str, key: &str) -> Result<Value> {
        info!("Getting app state for key '{}' in process: {}", key, process_id);
        
        Ok(serde_json::json!({
            "key": key,
            "value": null,
            "exists": false
        }))
    }
    
    pub async fn set_app_state(&self, process_id: &str, key: &str, value: Value) -> Result<()> {
        info!("Setting app state for key '{}' in process {} to: {}", 
              key, process_id, value);
        
        Ok(())
    }
}