mcp-appium-visual
Version:
MCP Server for Appium mobile automation with visual recovery
106 lines • 3.64 kB
JavaScript
import { spawn } from "child_process";
import * as path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/**
* Launcher for MCP-Appium that handles starting both the Appium server and the MCP server
*/
class McpAppiumLauncher {
constructor() {
this.appiumProcess = null;
this.mcpServerProcess = null;
this.appiumPort = 4723;
this.isAppiumRunning = false;
}
/**
* Start the Appium server
*/
startAppium() {
console.log("Starting Appium server...");
this.appiumProcess = spawn("appium", [
"--port",
this.appiumPort.toString(),
"--log-level",
"info",
"--log-timestamp",
]);
this.appiumProcess.stdout?.on("data", (data) => {
const output = data.toString();
console.log(`[Appium] ${output}`);
if (output.includes("Appium REST http interface listener started")) {
this.isAppiumRunning = true;
console.log(`Appium server started successfully on port ${this.appiumPort}`);
this.startMcpServer();
}
});
this.appiumProcess.stderr?.on("data", (data) => {
console.error(`[Appium Error] ${data.toString()}`);
});
this.appiumProcess.on("close", (code) => {
console.log(`Appium server exited with code ${code}`);
this.isAppiumRunning = false;
this.cleanup();
});
}
/**
* Start the MCP server
*/
startMcpServer() {
console.log("Starting MCP-Appium server...");
const serverPath = path.resolve(__dirname, "index.js");
this.mcpServerProcess = spawn("node", [serverPath]);
this.mcpServerProcess.stdout?.on("data", (data) => {
// MCP server uses stdout for communication, so we don't log it
});
this.mcpServerProcess.stderr?.on("data", (data) => {
console.log(`[MCP-Appium] ${data.toString()}`);
});
this.mcpServerProcess.on("close", (code) => {
console.log(`MCP-Appium server exited with code ${code}`);
this.cleanup();
});
console.log("MCP-Appium server started and ready to accept connections");
console.log("");
console.log("To use with Claude Desktop:");
console.log("1. Update your claude_desktop_config.json to include this server");
console.log("2. Restart Claude Desktop");
console.log("");
console.log("Press Ctrl+C to stop both servers");
}
/**
* Clean up processes when shutting down
*/
cleanup() {
if (this.appiumProcess && !this.appiumProcess.killed) {
this.appiumProcess.kill();
this.appiumProcess = null;
}
if (this.mcpServerProcess && !this.mcpServerProcess.killed) {
this.mcpServerProcess.kill();
this.mcpServerProcess = null;
}
process.exit();
}
/**
* Start the launcher
*/
start() {
// Handle process termination
process.on("SIGINT", () => {
console.log("Shutting down...");
this.cleanup();
});
process.on("SIGTERM", () => {
console.log("Shutting down...");
this.cleanup();
});
// Start servers
this.startAppium();
}
}
// Create and start the launcher
const launcher = new McpAppiumLauncher();
launcher.start();
//# sourceMappingURL=launcher.js.map