import { logger } from "$/shared/logger";
import fsp from "fs/promises";
import { Plugin } from "obsidian";
import path from "path";
import { BINARY_NAME } from "../constants";
import { getPlatform } from "./install";
import { getFileSystemAdapter } from "../utils/getFileSystemAdapter";
/**
* Uninstalls the MCP server by removing the binary and cleaning up configuration
*/
export async function uninstallServer(plugin: Plugin): Promise<void> {
try {
const adapter = getFileSystemAdapter(plugin);
if ("error" in adapter) {
throw new Error(adapter.error);
}
// Remove binary
const platform = getPlatform();
const binDir = path.join(
adapter.getBasePath(),
plugin.app.vault.configDir,
"plugins",
plugin.manifest.id,
"bin",
);
const binaryPath = path.join(binDir, BINARY_NAME[platform]);
try {
await fsp.unlink(binaryPath);
logger.info("Removed server binary", { binaryPath });
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
throw error;
}
// File doesn't exist, continue
}
// Remove bin directory if empty
try {
await fsp.rmdir(binDir);
logger.info("Removed empty bin directory", { binDir });
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOTEMPTY") {
throw error;
}
// Directory not empty, leave it
}
// Remove our entry from Claude config
// Note: We don't remove the entire config file since it may contain other server configs
const configPath = path.join(
process.env.HOME || process.env.USERPROFILE || "",
"Library/Application Support/Claude/claude_desktop_config.json",
);
try {
const content = await fsp.readFile(configPath, "utf8");
const config = JSON.parse(content);
if (config.mcpServers && config.mcpServers["obsidian-mcp-tools"]) {
delete config.mcpServers["obsidian-mcp-tools"];
await fsp.writeFile(configPath, JSON.stringify(config, null, 2));
logger.info("Removed server from Claude config", { configPath });
}
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
throw error;
}
// Config doesn't exist, nothing to clean up
}
logger.info("Server uninstall complete");
} catch (error) {
logger.error("Failed to uninstall server:", { error });
throw new Error(
`Failed to uninstall server: ${
error instanceof Error ? error.message : String(error)
}`,
);
}
}