UNPKG

create-mcp-i-app

Version:

Bootstrap MCP applications with identity features (temporary - use create-mcpi-app after Oct 7)

150 lines • 6.13 kB
import path from "path"; import fs from "fs-extra"; import { fileURLToPath } from "url"; import { fetchXMCPTemplate } from "./fetch-xmcp-template.js"; import { applyIdentityPreset } from "./apply-identity-preset.js"; import { renameFiles } from "./rename.js"; import { install } from "./install.js"; import { generateConfig } from "./generate-config.js"; import { validateProjectStructure, ensureLockfile, } from "./validate-project-structure.js"; import chalk from "chalk"; import crypto from "crypto"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Function to generate claim URL function generateClaimUrl(did, privateKeyBase64) { try { const timestamp = Date.now(); const message = `${did}:${timestamp}`; const privateKeyBuffer = Buffer.from(privateKeyBase64, "base64"); const privateKeyBytes = privateKeyBuffer.length === 64 ? privateKeyBuffer.subarray(0, 32) : privateKeyBuffer; const privateKey = crypto.createPrivateKey({ key: Buffer.concat([ Buffer.from("302e020100300506032b657004220420", "hex"), privateKeyBytes, ]), format: "der", type: "pkcs8", }); const signature = crypto.sign(null, Buffer.from(message), privateKey); const signatureBase64 = signature.toString("base64"); const params = new URLSearchParams({ did: did, timestamp: timestamp.toString(), signature: signatureBase64, }); return `https://knowthat.ai/agents/claim?${params.toString()}`; } catch (error) { console.error("Error generating claim URL:", error); return ""; } } /** * Create necessary project directories */ function createProjectDirectories(projectPath) { fs.ensureDirSync(path.join(projectPath, ".xmcp")); } /** * Create a new xmcp project with identity features */ export async function createProject(options) { const { projectPath, projectName, packageManager, transports, packageVersion, useLocalXmcp, xmcpVersion, xmcpChannel, deployToVercel, skipInstall, agentName = projectName, agentDescription = "XMCP-I server with identity features", agentRepository = "", skipIdentity = false, skipAnimation = false, fastAnimation = false, } = options; const warnings = []; let resolvedXmcpVersion = xmcpVersion; try { // Ensure the project directory exists fs.ensureDirSync(projectPath); // Fetch XMCP template from npm instead of using local templates console.log(chalk.blue("\nšŸ“ Scaffolding project...")); await fetchXMCPTemplate(projectPath, { xmcpVersion, xmcpChannel, packageManager, }); // Capture the resolved version for the result const packageJsonPath = path.join(projectPath, "package.json"); if (fs.existsSync(packageJsonPath)) { const packageJson = fs.readJsonSync(packageJsonPath); // Try to extract version from dependencies resolvedXmcpVersion = packageJson.dependencies?.xmcp || xmcpVersion || "unknown"; } // Rename special files (e.g., _gitignore to .gitignore) renameFiles(projectPath); // Apply identity preset on top of XMCP template await applyIdentityPreset({ projectPath, projectName, transports, noIdentity: skipIdentity, }); // Generate xmcp.config.ts based on selected transports generateConfig(projectPath, transports); // Add vercel.json if deployToVercel is true if (deployToVercel) { // Create a basic vercel.json for XMCP-I deployment const vercelConfig = { functions: { "src/server.ts": { runtime: "@vercel/node@3", }, }, rewrites: [ { source: "/(.*)", destination: "/src/server.ts", }, ], }; fs.writeJsonSync(path.join(projectPath, "vercel.json"), vercelConfig, { spaces: 2, }); } // Create necessary project directories createProjectDirectories(projectPath); // Install project dependencies if (!skipInstall) { install(projectPath, packageManager, packageVersion); // Ensure lockfile is properly created ensureLockfile(projectPath, packageManager); } // Validate project structure meets requirements const validation = validateProjectStructure(projectPath, !skipIdentity); if (!validation.valid) { console.warn(chalk.yellow("āš ļø Project structure validation issues:")); for (const issue of validation.issues) { console.warn(chalk.yellow(` - ${issue}`)); warnings.push(...validation.issues); } } // Identity setup is now handled by the CLI after scaffolding if (!skipIdentity) { console.log(chalk.blue("\nšŸ” Identity setup will be handled by the CLI")); console.log(chalk.gray(" Run 'mcpi init' after scaffolding to set up identity")); } return { success: true, projectPath, xmcpVersion: resolvedXmcpVersion || "unknown", identityEnabled: !skipIdentity, warnings: warnings.length > 0 ? warnings : undefined, }; } catch (error) { console.error(chalk.red("Failed to create project:"), error); return { success: false, projectPath, xmcpVersion: resolvedXmcpVersion || "unknown", identityEnabled: !skipIdentity, warnings: [ `Project creation failed: ${error instanceof Error ? error.message : String(error)}`, ], }; } } //# sourceMappingURL=create.js.map