# repair_outlook_database

Locates and prepares to run the Microsoft Outlook database repair utility. On macOS, identifies the Outlook Database Utility or Profile Manager. On Windows, locates scanpst.exe. Use when Outlook crashes, hangs, or shows data corruption errors.

## Metadata

#### Name

repair_outlook_database

#### Updated

last month

#### Source

[GitHub source](https://github.com/idemeum/skills/blob/main/repairOutlookDatabase.ts)

#### Risk

Medium

#### Requires consent

true

#### Affected scope

user

## Code

```
/**
 * mcp/skills/repairOutlookDatabase.ts — repair_outlook_database skill
 *
 * Locates and prepares to run the Microsoft Outlook database repair utility.
 * On macOS, identifies the Outlook Database Utility or Profile Manager.
 * On Windows, locates scanpst.exe.
 * Use when Outlook crashes, hangs, or shows data corruption errors.
 *
 * Platform strategy
 * -----------------
 * darwin  Checks /Applications/Microsoft Outlook.app/Contents/SharedSupport/
 *         and ~/Library/Group Containers/UBF8T346G9.Office/ for profile data.
 * win32   Searches common scanpst.exe paths and PST/OST files via PowerShell.
 *
 * Smoke test
 *   npx tsx -r dotenv/config mcp/skills/repairOutlookDatabase.ts
 */

import * as os       from "os";
import * as nodePath from "path";
import * as fs       from "fs/promises";
import { exec }      from "child_process";
import { promisify } from "util";
import { z }         from "zod";

const execAsync = promisify(exec);

// -- Meta ---------------------------------------------------------------------

export const meta = {
  name: "repair_outlook_database",
  description:
    "Locates and prepares to run the Microsoft Outlook database repair utility. " +
    "On macOS, identifies the Outlook Database Utility or Profile Manager. " +
    "On Windows, locates scanpst.exe. " +
    "Use when Outlook crashes, hangs, or shows data corruption errors.",
  riskLevel:       "medium",
  destructive:     true,
  requiresConsent: true,
  supportsDryRun:  true,
  affectedScope:   ["user"],
  auditRequired:   true,
  tccCategories:   ["FullDiskAccess"],
  schema: {
    dryRun: z
      .boolean()
      .optional()
      .describe(
        "If true, locate repair tool and database files without running repair. Default: true",
      ),
  },
} as const;

// -- Types --------------------------------------------------------------------

interface RepairOutlookResult {
  toolFound:       boolean;
  toolPath:        string | null;
  databaseFiles:   string[];
  outlookRunning:  boolean;
  dryRun:          boolean;
  message:         string;
}

// -- PowerShell helper --------------------------------------------------------

async function runPS(script: string): Promise<string> {
  const encoded = Buffer.from(script, "utf16le").toString("base64");
  const { stdout } = await execAsync(
    `powershell.exe -NoProfile -NonInteractive -EncodedCommand ${encoded}`,
    { maxBuffer: 20 * 1024 * 1024, timeout: 30_000 },
  );
  return stdout.trim();
}

// -- darwin implementation ----------------------------------------------------

async function repairOutlookDarwin(dryRun: boolean): Promise<RepairOutlookResult> {
  // Check if Outlook is running
  let outlookRunning = false;
  try {
    const { stdout } = await execAsync("pgrep -x 'Microsoft Outlook'", { timeout: 3_000 });
    outlookRunning = stdout.trim().length > 0;
  } catch {
    outlookRunning = false;
  }

// Search for Outlook Database Utility
  const sharedSupportDir =
    "/Applications/Microsoft Outlook.app/Contents/SharedSupport";
  let toolPath: string | null = null;

const candidateTools = [\
    nodePath.join(sharedSupportDir, "Outlook Database Utility.app"),\
    nodePath.join(sharedSupportDir, "Outlook Profile Manager.app"),\
  ];

for (const candidate of candidateTools) {
    try {
      await fs.access(candidate);
      toolPath = candidate;
      break;
    } catch {
      // Not found — try next
    }
  }

// Look for profile/database data
  const profileBase = nodePath.join(
    os.homedir(),
    "Library",
    "Group Containers",
    "UBF8T346G9.Office",
  );
  const databaseFiles: string[] = [];

try {
    await fs.access(profileBase);
    databaseFiles.push(profileBase);

// Also look for specific database files
    const outlookDataDir = nodePath.join(
      profileBase,
      "Outlook",
      "Outlook 15 Profiles",
    );
    try {
      await fs.access(outlookDataDir);
      databaseFiles.push(outlookDataDir);
    } catch {
      // Sub-directory may not exist
    }
  } catch {
    // Group container not found — Outlook may not be installed
  }

// Execute-time guard: never open the repair tool against a live database.
  if (!dryRun && outlookRunning) {
    return {
      toolFound: toolPath !== null,
      toolPath,
      databaseFiles,
      outlookRunning,
      dryRun,
      message:
        "Microsoft Outlook is still running — quit it completely, then re-run the repair. " +
        "Running the database repair while Outlook is open can fail or corrupt the database.",
    };
  }

// Open the repair tool if requested
  if (!dryRun && toolPath) {
    try {
      await execAsync(`open \
