#!/usr/bin/env node
/**
* Build script for creating MCP WordPress DXT package
*/
import fs from "fs";
import path from "path";
import { execSync } from "child_process";
import archiver from "archiver";
const BUILD_DIR = "dxt-build";
const DXT_DIR = "dxt";
const PACKAGE_NAME = "mcp-wordpress.dxt";
async function buildDXT() {
console.log("ποΈ Building MCP WordPress DXT package...\n");
try {
// Clean previous build
if (fs.existsSync(BUILD_DIR)) {
console.log("π§Ή Cleaning previous build...");
fs.rmSync(BUILD_DIR, { recursive: true });
}
// Create build directory
fs.mkdirSync(BUILD_DIR);
console.log("π Created build directory");
// Build TypeScript
console.log("π¨ Building TypeScript...");
execSync("npm run build", { stdio: "inherit" });
// Copy manifest
console.log("π Copying manifest...");
fs.copyFileSync(path.join(DXT_DIR, "manifest.json"), path.join(BUILD_DIR, "manifest.json"));
// Copy icon
console.log("πΌοΈ Copying icon...");
fs.copyFileSync(path.join(DXT_DIR, "icon.png"), path.join(BUILD_DIR, "icon.png"));
// Copy main entry point to root
console.log("π¦ Copying main entry point...");
fs.copyFileSync("dist/index.js", path.join(BUILD_DIR, "index.js"));
// Copy essential dependencies directly
console.log("π¦ Copying compiled code...");
copyDirectory("dist", path.join(BUILD_DIR, "dist"));
// Copy package.json first for dependency installation
console.log("π Copying package.json for dependencies...");
fs.copyFileSync("package.json", path.join(BUILD_DIR, "package.json"));
fs.copyFileSync("package-lock.json", path.join(BUILD_DIR, "package-lock.json"));
// Install production dependencies
console.log("π¦ Installing production dependencies...");
execSync("npm ci --omit=dev", { cwd: BUILD_DIR, stdio: "inherit" });
// Update package.json to production-only version
const packageJson = JSON.parse(fs.readFileSync("package.json", "utf8"));
const productionPackageJson = {
name: packageJson.name,
version: packageJson.version,
description: packageJson.description,
type: packageJson.type, // Essential for ES modules support
main: "index.js", // Point to root index.js
dependencies: packageJson.dependencies,
engines: packageJson.engines,
};
fs.writeFileSync(path.join(BUILD_DIR, "package.json"), JSON.stringify(productionPackageJson, null, 2));
// Remove package-lock.json as it's no longer needed after install
fs.rmSync(path.join(BUILD_DIR, "package-lock.json"));
// Create README for DXT
console.log("π Creating DXT README...");
const dxtReadme = `# WordPress MCP Server Desktop Extension
This is a Desktop Extension (DXT) package for the WordPress MCP Server.
## Installation
1. Download the .dxt file
2. Open Claude Desktop
3. Install the extension through the Extensions menu
## Configuration
After installation, you'll be prompted to configure:
- WordPress Site URL
- Username
- Application Password
- Authentication Method (optional)
- Debug Mode (optional)
## Features
- 59 WordPress management tools
- Multi-site support
- Performance monitoring
- Intelligent caching
- Real-time analytics
For more information, visit: https://github.com/docdyhr/mcp-wordpress
`;
fs.writeFileSync(path.join(BUILD_DIR, "README.md"), dxtReadme);
// Create the DXT package (ZIP file)
console.log("π¦ Creating DXT package...");
const output = fs.createWriteStream(PACKAGE_NAME);
const archive = archiver("zip", { zlib: { level: 9 } });
archive.pipe(output);
archive.directory(BUILD_DIR, false);
await new Promise((resolve, reject) => {
output.on("close", resolve);
archive.on("error", reject);
archive.finalize();
});
console.log(`\nβ
DXT package created: ${PACKAGE_NAME}`);
console.log(`π Package size: ${(fs.statSync(PACKAGE_NAME).size / 1024 / 1024).toFixed(2)} MB`);
// Validate the package
console.log("\nπ Validating DXT package...");
const manifest = JSON.parse(fs.readFileSync(path.join(BUILD_DIR, "manifest.json"), "utf8"));
// Basic validation
const requiredFields = ["dxt_version", "name", "version", "description", "author", "server"];
const missingFields = requiredFields.filter((field) => !manifest[field]);
if (missingFields.length > 0) {
console.error("β Missing required fields in manifest:", missingFields);
process.exit(1);
}
console.log("β
Manifest validation passed");
console.log(`π¦ Extension: ${manifest.name} v${manifest.version}`);
console.log(`π§ Tools: ${manifest.tools ? manifest.tools.length : 0}`);
console.log(`π¬ Prompts: ${manifest.prompts ? manifest.prompts.length : 0}`);
console.log("\nπ DXT package build completed successfully!");
console.log(`\nTo install the package:`);
console.log(`1. Open Claude Desktop`);
console.log(`2. Go to Extensions menu`);
console.log(`3. Install the ${PACKAGE_NAME} file`);
console.log(`4. Configure your WordPress credentials`);
} catch (error) {
console.error("β Build failed:", error.message);
process.exit(1);
}
}
// Run the build
buildDXT().catch((error) => {
console.error("β Build failed:", error.message);
process.exit(1);
});
function copyDirectory(src, dest) {
if (!fs.existsSync(dest)) {
fs.mkdirSync(dest, { recursive: true });
}
const items = fs.readdirSync(src);
for (const item of items) {
const srcPath = path.join(src, item);
const destPath = path.join(dest, item);
if (fs.statSync(srcPath).isDirectory()) {
copyDirectory(srcPath, destPath);
} else {
fs.copyFileSync(srcPath, destPath);
}
}
}