You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@mcp-apps-kit/create-app

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mcp-apps-kit/create-app - npm Package Compare versions

Comparing version
0.2.2
to
0.2.3
+268
-35
dist/cli.js

@@ -9,4 +9,30 @@ #!/usr/bin/env node

function getReactTemplate(name) {
return {
var cachedVersions = null;
function fetchLatestVersion(packageName) {
try {
const result = execSync(`npm view ${packageName} version`, {
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"]
}).trim();
return `^${result}`;
} catch {
return "^0.2.0";
}
}
function getPackageVersions() {
if (cachedVersions) {
return cachedVersions;
}
cachedVersions = {
core: fetchLatestVersion("@mcp-apps-kit/core"),
ui: fetchLatestVersion("@mcp-apps-kit/ui"),
uiReact: fetchLatestVersion("@mcp-apps-kit/ui-react")
};
return cachedVersions;
}
function getReactTemplate(name, vercel = false) {
const uiOutputDir = vercel ? "public" : "dist";
const packageManager = vercel ? "npm" : "pnpm";
const versions = getPackageVersions();
const files = {
"package.json": JSON.stringify(

@@ -18,6 +44,6 @@ {

scripts: {
dev: 'concurrently "pnpm dev:server" "pnpm dev:ui"',
dev: `concurrently "${packageManager} run dev:server" "${packageManager} run dev:ui"`,
"dev:server": "tsx watch server/index.ts",
"dev:ui": "vite --config ui/vite.config.ts",
build: "pnpm build:ui && tsc",
build: `${packageManager} run build:ui && tsc`,
"build:ui": "vite build --config ui/vite.config.ts",

@@ -27,8 +53,9 @@ start: "node dist/server/index.js"

dependencies: {
"@mcp-apps-kit/core": "^0.1.0",
"@mcp-apps-kit/ui": "^0.1.0",
"@mcp-apps-kit/ui-react": "^0.1.0",
"@mcp-apps-kit/core": versions.core,
"@mcp-apps-kit/ui": versions.ui,
"@mcp-apps-kit/ui-react": versions.uiReact,
react: "^18.2.0",
"react-dom": "^18.2.0",
zod: "^3.22.0"
zod: "^3.22.0",
...vercel ? { express: "^4.21.0" } : {}
},

@@ -68,6 +95,9 @@ devDependencies: {

),
"server/index.ts": `/**
"server/index.ts": vercel ? `/**
* ${name} - MCP Server
*/
// Required for Vercel to detect Express
import "express";
import { createApp } from "@mcp-apps-kit/core";

@@ -102,2 +132,50 @@ import { z } from "zod";

greeting: {
html: "./${uiOutputDir}/index.html",
description: "Greeting widget",
prefersBorder: true,
},
},
});
// Only start locally - Vercel uses the exported Express app
if (!process.env.VERCEL) {
await app.start({ port: 3000 });
console.log("MCP server running on http://localhost:3000");
}
// Export Express app for Vercel
export default app.expressApp;
` : `/**
* ${name} - MCP Server
*/
import { createApp } from "@mcp-apps-kit/core";
import { z } from "zod";
const app = createApp({
name: "${name}",
version: "0.1.0",
tools: {
hello: {
description: "Say hello to someone",
input: z.object({
name: z.string().describe("Name to greet"),
}),
output: z.object({
message: z.string(),
timestamp: z.string(),
}),
handler: async ({ name }) => {
return {
message: \`Hello, \${name}!\`,
timestamp: new Date().toISOString(),
};
},
ui: "greeting",
},
},
ui: {
greeting: {
html: "./ui/dist/index.html",

@@ -271,3 +349,3 @@ description: "Greeting widget",

build: {
outDir: "dist",
outDir: "${uiOutputDir}",
emptyOutDir: true,

@@ -279,2 +357,3 @@ },

dist/
public/
*.log

@@ -291,4 +370,4 @@ .env

\`\`\`bash
pnpm install
pnpm dev
${packageManager} install
${packageManager} run dev
\`\`\`

@@ -299,3 +378,3 @@

\`\`\`bash
pnpm build
${packageManager} run build
\`\`\`

@@ -317,7 +396,44 @@

\`\`\`
${vercel ? `
## Deploy to Vercel
This project is configured for Vercel deployment:
\`\`\`bash
vercel deploy
\`\`\`
Then use the deployed URL as your MCP server endpoint.
` : ""}
`
};
if (vercel) {
files["vercel.json"] = JSON.stringify(
{
installCommand: "npm install",
buildCommand: "npm run build:ui",
outputDirectory: ".",
functions: {
"server/index.ts": {
includeFiles: `${uiOutputDir}/**`
}
},
rewrites: [
{
source: "/(.*)",
destination: "/server/index.ts"
}
]
},
null,
2
);
}
return files;
}
function getVanillaTemplate(name) {
return {
function getVanillaTemplate(name, vercel = false) {
const uiOutputDir = vercel ? "public" : "dist";
const packageManager = vercel ? "npm" : "pnpm";
const versions = getPackageVersions();
const files = {
"package.json": JSON.stringify(

@@ -329,6 +445,6 @@ {

scripts: {
dev: 'concurrently "pnpm dev:server" "pnpm dev:ui"',
dev: `concurrently "${packageManager} run dev:server" "${packageManager} run dev:ui"`,
"dev:server": "tsx watch server/index.ts",
"dev:ui": "vite --config ui/vite.config.ts",
build: "pnpm build:ui && tsc",
build: `${packageManager} run build:ui && tsc`,
"build:ui": "vite build --config ui/vite.config.ts",

@@ -338,5 +454,6 @@ start: "node dist/server/index.js"

dependencies: {
"@mcp-apps-kit/core": "^0.1.0",
"@mcp-apps-kit/ui": "^0.1.0",
zod: "^3.22.0"
"@mcp-apps-kit/core": versions.core,
"@mcp-apps-kit/ui": versions.ui,
zod: "^3.22.0",
...vercel ? { express: "^4.21.0" } : {}
},

@@ -372,6 +489,9 @@ devDependencies: {

),
"server/index.ts": `/**
"server/index.ts": vercel ? `/**
* ${name} - MCP Server
*/
// Required for Vercel to detect Express
import "express";
import { createApp } from "@mcp-apps-kit/core";

@@ -406,2 +526,50 @@ import { z } from "zod";

greeting: {
html: "./${uiOutputDir}/index.html",
description: "Greeting widget",
prefersBorder: true,
},
},
});
// Only start locally - Vercel uses the exported Express app
if (!process.env.VERCEL) {
await app.start({ port: 3000 });
console.log("MCP server running on http://localhost:3000");
}
// Export Express app for Vercel
export default app.expressApp;
` : `/**
* ${name} - MCP Server
*/
import { createApp } from "@mcp-apps-kit/core";
import { z } from "zod";
const app = createApp({
name: "${name}",
version: "0.1.0",
tools: {
hello: {
description: "Say hello to someone",
input: z.object({
name: z.string().describe("Name to greet"),
}),
output: z.object({
message: z.string(),
timestamp: z.string(),
}),
handler: async ({ name }) => {
return {
message: \`Hello, \${name}!\`,
timestamp: new Date().toISOString(),
};
},
ui: "greeting",
},
},
ui: {
greeting: {
html: "./ui/dist/index.html",

@@ -564,3 +732,3 @@ description: "Greeting widget",

build: {
outDir: "dist",
outDir: "${uiOutputDir}",
emptyOutDir: true,

@@ -572,2 +740,3 @@ },

dist/
public/
*.log

@@ -584,4 +753,4 @@ .env

\`\`\`bash
pnpm install
pnpm dev
${packageManager} install
${packageManager} run dev
\`\`\`

@@ -592,3 +761,3 @@

\`\`\`bash
pnpm build
${packageManager} run build
\`\`\`

@@ -610,7 +779,48 @@

\`\`\`
${vercel ? `
## Deploy to Vercel
This project is configured for Vercel deployment:
\`\`\`bash
vercel deploy
\`\`\`
Then use the deployed URL as your MCP server endpoint.
` : ""}
`
};
if (vercel) {
files["vercel.json"] = JSON.stringify(
{
installCommand: "npm install",
buildCommand: "npm run build:ui",
outputDirectory: ".",
functions: {
"server/index.ts": {
includeFiles: `${uiOutputDir}/**`
}
},
rewrites: [
{
source: "/(.*)",
destination: "/server/index.ts"
}
]
},
null,
2
);
}
return files;
}
async function scaffoldProject(options) {
const { name, template, directory, skipInstall = false, skipGit = false } = options;
const {
name,
template,
directory,
vercel = false,
skipInstall = false,
skipGit = false
} = options;
const projectDir = directory ?? path.resolve(process.cwd(), name);

@@ -625,3 +835,3 @@ if (fs.existsSync(projectDir)) {

}
const templateFiles = template === "react" ? getReactTemplate(name) : getVanillaTemplate(name);
const templateFiles = template === "react" ? getReactTemplate(name, vercel) : getVanillaTemplate(name, vercel);
for (const [filePath, content] of Object.entries(templateFiles)) {

@@ -643,6 +853,10 @@ const fullPath = path.join(projectDir, filePath);

try {
try {
execSync("pnpm install", { cwd: projectDir, stdio: "inherit" });
} catch {
if (vercel) {
execSync("npm install", { cwd: projectDir, stdio: "inherit" });
} else {
try {
execSync("pnpm install", { cwd: projectDir, stdio: "inherit" });
} catch {
execSync("npm install", { cwd: projectDir, stdio: "inherit" });
}
}

@@ -679,2 +893,3 @@ } catch {

skipGit: false,
vercel: false,
interactive: false

@@ -694,3 +909,3 @@ };

"react"
).option("-d, --directory <path>", "Directory to create project in").option("--skip-install", "Skip installing dependencies", false).option("--skip-git", "Skip initializing git repository", false).allowUnknownOption(false).parse(["node", "create-mcp-apps-kit", ...args]);
).option("-d, --directory <path>", "Directory to create project in").option("--skip-install", "Skip installing dependencies", false).option("--skip-git", "Skip initializing git repository", false).option("--vercel", "Add Vercel deployment configuration", false).allowUnknownOption(false).parse(["node", "create-mcp-apps-kit", ...args]);
const options = program.opts();

@@ -704,2 +919,3 @@ const [name] = program.args;

skipGit: options.skipGit,
vercel: options.vercel,
interactive: !name

@@ -737,2 +953,8 @@ };

type: "confirm",
name: "vercel",
message: "Add Vercel deployment setup?",
initial: true
},
{
type: "confirm",
name: "skipInstall",

@@ -756,2 +978,3 @@ message: "Skip installing dependencies?",

template: response.template,
vercel: response.vercel,
skipInstall: response.skipInstall,

@@ -781,3 +1004,4 @@ skipGit: response.skipGit

skipInstall: cliOptions.skipInstall,
skipGit: cliOptions.skipGit
skipGit: cliOptions.skipGit,
vercel: cliOptions.vercel
};

@@ -787,4 +1011,8 @@ }

console.log(chalk.blue(`Creating ${options.name} with ${options.template} template...`));
if (options.vercel) {
console.log(chalk.blue("Setting up for Vercel deployment..."));
}
console.log();
await scaffoldProject(options);
const packageManager = options.vercel ? "npm" : "pnpm";
console.log();

@@ -796,7 +1024,12 @@ console.log(chalk.green("\u2713 Project created successfully!"));

if (!options.skipInstall) {
console.log(chalk.cyan(" pnpm dev"));
console.log(chalk.cyan(` ${packageManager} run dev`));
} else {
console.log(chalk.cyan(" pnpm install"));
console.log(chalk.cyan(" pnpm dev"));
console.log(chalk.cyan(` ${packageManager} install`));
console.log(chalk.cyan(` ${packageManager} run dev`));
}
if (options.vercel) {
console.log();
console.log("To deploy to Vercel:");
console.log(chalk.cyan(" vercel deploy"));
}
console.log();

@@ -803,0 +1036,0 @@ } catch (error) {

+1
-1

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/index.ts","../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * @mcp-apps-kit/create-app\n *\n * Project scaffolding for MCP applications.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CreateAppOptions {\n name: string;\n template: \"react\" | \"vanilla\";\n directory?: string;\n skipInstall?: boolean;\n skipGit?: boolean;\n}\n\n// =============================================================================\n// Template Content\n// =============================================================================\n\nfunction getReactTemplate(name: string): Record<string, string> {\n return {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: 'concurrently \"pnpm dev:server\" \"pnpm dev:ui\"',\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: \"pnpm build:ui && tsc\",\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": \"^0.1.0\",\n \"@mcp-apps-kit/ui\": \"^0.1.0\",\n \"@mcp-apps-kit/ui-react\": \"^0.1.0\",\n react: \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n zod: \"^3.22.0\",\n },\n devDependencies: {\n \"@types/react\": \"^18.2.0\",\n \"@types/react-dom\": \"^18.2.0\",\n \"@vitejs/plugin-react\": \"^4.2.0\",\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n jsx: \"react-jsx\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/App.tsx\": `/**\n * ${name} - UI Component\n */\n\nimport {\n useAppsClient,\n useHostContext,\n useDocumentTheme,\n useHostStyleVariables,\n} from \"@mcp-apps-kit/ui-react\";\n\nexport function App() {\n const client = useAppsClient();\n const context = useHostContext();\n\n // Apply theme and host styles\n useDocumentTheme(\"light\", \"dark\");\n useHostStyleVariables();\n\n // Get tool output from client\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n\n return (\n <div className=\"container\">\n {output?.message ? (\n <div className=\"greeting\">\n <h1>{output.message}</h1>\n <p className=\"timestamp\">Sent at: {output.timestamp}</p>\n </div>\n ) : (\n <p className=\"waiting\">Waiting for greeting...</p>\n )}\n\n <button\n className=\"button\"\n onClick={() => client.sendFollowUpMessage(\"Please greet me again!\")}\n >\n Request New Greeting\n </button>\n\n <footer className=\"meta\">\n Theme: {context.theme} | Locale: {context.locale}\n </footer>\n </div>\n );\n}\n`,\n \"ui/src/main.tsx\": `/**\n * ${name} - UI Entry Point\n */\n\nimport React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { AppsProvider } from \"@mcp-apps-kit/ui-react\";\nimport { App } from \"./App\";\nimport \"./styles.css\";\n\nconst root = document.getElementById(\"root\");\nif (!root) throw new Error(\"Root element not found\");\n\ncreateRoot(root).render(\n <React.StrictMode>\n <AppsProvider>\n <App />\n </AppsProvider>\n </React.StrictMode>\n);\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [react(), viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"dist\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\npnpm install\npnpm dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\npnpm build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n`,\n };\n}\n\nfunction getVanillaTemplate(name: string): Record<string, string> {\n return {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: 'concurrently \"pnpm dev:server\" \"pnpm dev:ui\"',\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: \"pnpm build:ui && tsc\",\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": \"^0.1.0\",\n \"@mcp-apps-kit/ui\": \"^0.1.0\",\n zod: \"^3.22.0\",\n },\n devDependencies: {\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/main.ts\": `/**\n * ${name} - UI Entry Point\n */\n\nimport { createClient } from \"@mcp-apps-kit/ui\";\nimport \"./styles.css\";\n\nasync function main() {\n const client = await createClient();\n\n // Get container\n const container = document.getElementById(\"app\");\n if (!container) throw new Error(\"Container not found\");\n\n // Render initial UI\n render(container, client);\n\n // Subscribe to context changes\n client.onHostContextChange((context) => {\n document.documentElement.className = context.theme;\n render(container, client);\n });\n}\n\nfunction render(container: HTMLElement, client: ReturnType<typeof createClient> extends Promise<infer T> ? T : never) {\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n const context = client.hostContext;\n\n container.innerHTML = \\`\n <div class=\"container\">\n \\${output?.message ? \\`\n <div class=\"greeting\">\n <h1>\\${output.message}</h1>\n <p class=\"timestamp\">Sent at: \\${output.timestamp}</p>\n </div>\n \\` : \\`\n <p class=\"waiting\">Waiting for greeting...</p>\n \\`}\n\n <button class=\"button\" id=\"request-btn\">\n Request New Greeting\n </button>\n\n <footer class=\"meta\">\n Theme: \\${context.theme} | Locale: \\${context.locale}\n </footer>\n </div>\n \\`;\n\n // Add event listener\n const btn = document.getElementById(\"request-btn\");\n btn?.addEventListener(\"click\", () => {\n client.sendFollowUpMessage(\"Please greet me again!\");\n });\n}\n\nmain();\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.ts\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"dist\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\npnpm install\npnpm dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\npnpm build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n`,\n };\n}\n\n// =============================================================================\n// Scaffolding Logic\n// =============================================================================\n\n/**\n * Scaffold a new MCP application project\n */\nexport async function scaffoldProject(options: CreateAppOptions): Promise<void> {\n const { name, template, directory, skipInstall = false, skipGit = false } = options;\n\n // Determine project directory\n const projectDir = directory ?? path.resolve(process.cwd(), name);\n\n // Check if directory exists and is not empty\n if (fs.existsSync(projectDir)) {\n const files = fs.readdirSync(projectDir);\n if (files.length > 0) {\n throw new Error(`Directory ${projectDir} is not empty. Please use an empty directory.`);\n }\n } else {\n fs.mkdirSync(projectDir, { recursive: true });\n }\n\n // Get template files\n const templateFiles = template === \"react\" ? getReactTemplate(name) : getVanillaTemplate(name);\n\n // Write all files\n for (const [filePath, content] of Object.entries(templateFiles)) {\n const fullPath = path.join(projectDir, filePath);\n const dir = path.dirname(fullPath);\n\n // Create directory if needed\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n fs.writeFileSync(fullPath, content, \"utf-8\");\n }\n\n // Initialize git repository\n if (!skipGit) {\n try {\n execSync(\"git init\", { cwd: projectDir, stdio: \"ignore\" });\n } catch {\n // Ignore git init errors (git may not be installed)\n }\n }\n\n // Install dependencies\n if (!skipInstall) {\n try {\n // Try pnpm first, fall back to npm\n try {\n execSync(\"pnpm install\", { cwd: projectDir, stdio: \"inherit\" });\n } catch {\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n }\n } catch {\n // eslint-disable-next-line no-console\n console.warn(\"Warning: Could not install dependencies automatically.\");\n }\n }\n}\n","/**\n * @mcp-apps-kit/create-app CLI\n *\n * Command-line interface for scaffolding MCP applications.\n */\n/* eslint-disable no-console */\n\nimport { Command, InvalidArgumentError } from \"commander\";\nimport prompts from \"prompts\";\nimport chalk from \"chalk\";\nimport { scaffoldProject } from \"./index.js\";\nimport type { CreateAppOptions } from \"./index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CLIOptions {\n name?: string;\n template: \"react\" | \"vanilla\";\n directory?: string;\n skipInstall: boolean;\n skipGit: boolean;\n interactive: boolean;\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\n/**\n * Validate a project name follows npm package naming conventions\n */\nexport function validateProjectName(name: string): boolean {\n if (!name || name.length === 0) {\n return false;\n }\n\n // Check for scoped packages\n if (name.startsWith(\"@\")) {\n const parts = name.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) return false;\n const scope = parts[0].slice(1);\n const pkg = parts[1];\n return validateSimpleName(scope) && validateSimpleName(pkg);\n }\n\n return validateSimpleName(name);\n}\n\nfunction validateSimpleName(name: string): boolean {\n // npm package name rules:\n // - lowercase\n // - one word (no spaces)\n // - can contain hyphens, underscores, dots\n // - cannot start with dot or underscore\n const validPattern = /^[a-z][a-z0-9._-]*$/;\n return validPattern.test(name);\n}\n\n// =============================================================================\n// Argument Parsing\n// =============================================================================\n\nconst VALID_TEMPLATES = [\"react\", \"vanilla\"] as const;\ntype Template = (typeof VALID_TEMPLATES)[number];\n\n/**\n * Parse CLI arguments\n */\nexport function parseArgs(args: string[]): CLIOptions {\n let result: CLIOptions = {\n template: \"react\",\n skipInstall: false,\n skipGit: false,\n interactive: false,\n };\n\n const program = new Command()\n .name(\"create-mcp-apps-kit\")\n .description(\"Scaffold a new MCP application\")\n .version(\"0.1.0\")\n .argument(\"[name]\", \"Project name\")\n .option(\n \"-t, --template <template>\",\n \"Template to use (react, vanilla)\",\n (value) => {\n if (!VALID_TEMPLATES.includes(value as Template)) {\n throw new InvalidArgumentError(\n `Invalid template: ${value}. Must be one of: ${VALID_TEMPLATES.join(\", \")}`\n );\n }\n return value as Template;\n },\n \"react\"\n )\n .option(\"-d, --directory <path>\", \"Directory to create project in\")\n .option(\"--skip-install\", \"Skip installing dependencies\", false)\n .option(\"--skip-git\", \"Skip initializing git repository\", false)\n .allowUnknownOption(false)\n .parse([\"node\", \"create-mcp-apps-kit\", ...args]);\n\n const options = program.opts<{\n template: Template;\n directory?: string;\n skipInstall: boolean;\n skipGit: boolean;\n }>();\n const [name] = program.args;\n\n result = {\n name,\n template: options.template,\n directory: options.directory,\n skipInstall: options.skipInstall,\n skipGit: options.skipGit,\n interactive: !name,\n };\n\n return result;\n}\n\n// =============================================================================\n// Interactive Mode\n// =============================================================================\n\nasync function runInteractive(): Promise<CreateAppOptions> {\n console.log();\n console.log(chalk.bold(\"🚀 Create a new MCP application\"));\n console.log();\n\n const response = await prompts<\"name\" | \"template\" | \"skipInstall\" | \"skipGit\">([\n {\n type: \"text\",\n name: \"name\",\n message: \"Project name:\",\n validate: (value: string) => {\n if (!validateProjectName(value)) {\n return \"Invalid project name. Must be lowercase, no spaces, valid npm package name.\";\n }\n return true;\n },\n },\n {\n type: \"select\",\n name: \"template\",\n message: \"Template:\",\n choices: [\n { title: \"React\", value: \"react\", description: \"React + TypeScript with hooks\" },\n { title: \"Vanilla\", value: \"vanilla\", description: \"Vanilla TypeScript\" },\n ],\n initial: 0,\n },\n {\n type: \"confirm\",\n name: \"skipInstall\",\n message: \"Skip installing dependencies?\",\n initial: false,\n },\n {\n type: \"confirm\",\n name: \"skipGit\",\n message: \"Skip initializing git?\",\n initial: false,\n },\n ]);\n\n if (!response.name) {\n console.log(chalk.yellow(\"Cancelled.\"));\n process.exit(0);\n }\n\n return {\n name: response.name as string,\n template: response.template as \"react\" | \"vanilla\",\n skipInstall: response.skipInstall as boolean,\n skipGit: response.skipGit as boolean,\n };\n}\n\n// =============================================================================\n// Main Entry Point\n// =============================================================================\n\nasync function main(): Promise<void> {\n try {\n const cliOptions = parseArgs(process.argv.slice(2));\n\n let options: CreateAppOptions;\n\n if (cliOptions.interactive) {\n options = await runInteractive();\n } else {\n if (!cliOptions.name) {\n console.error(chalk.red(\"Error: Project name is required\"));\n process.exit(1);\n }\n\n if (!validateProjectName(cliOptions.name)) {\n console.error(chalk.red(\"Error: Invalid project name. Must be a valid npm package name.\"));\n process.exit(1);\n }\n\n options = {\n name: cliOptions.name,\n template: cliOptions.template,\n directory: cliOptions.directory,\n skipInstall: cliOptions.skipInstall,\n skipGit: cliOptions.skipGit,\n };\n }\n\n console.log();\n console.log(chalk.blue(`Creating ${options.name} with ${options.template} template...`));\n console.log();\n\n await scaffoldProject(options);\n\n console.log();\n console.log(chalk.green(\"✓ Project created successfully!\"));\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.cyan(` cd ${options.directory ?? options.name}`));\n if (!options.skipInstall) {\n console.log(chalk.cyan(\" pnpm dev\"));\n } else {\n console.log(chalk.cyan(\" pnpm install\"));\n console.log(chalk.cyan(\" pnpm dev\"));\n }\n console.log();\n } catch (error) {\n console.error(chalk.red(\"Error:\"), error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n\n// Run if executed directly\nvoid main();\n"]}
{"version":3,"sources":["../src/index.ts","../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * @mcp-apps-kit/create-app\n *\n * Project scaffolding for MCP applications.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CreateAppOptions {\n name: string;\n template: \"react\" | \"vanilla\";\n directory?: string;\n vercel?: boolean;\n skipInstall?: boolean;\n skipGit?: boolean;\n}\n\n// =============================================================================\n// Version Detection\n// =============================================================================\n\ninterface PackageVersions {\n core: string;\n ui: string;\n uiReact: string;\n}\n\n// Cache for fetched versions\nlet cachedVersions: PackageVersions | null = null;\n\n/**\n * Fetch the latest version of a package from npm registry\n */\nfunction fetchLatestVersion(packageName: string): string {\n try {\n const result = execSync(`npm view ${packageName} version`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n return `^${result}`;\n } catch {\n // Fallback to a reasonable default if we can't fetch\n return \"^0.2.0\";\n }\n}\n\n/**\n * Get the versions of @mcp-apps-kit packages from npm registry\n */\nfunction getPackageVersions(): PackageVersions {\n if (cachedVersions) {\n return cachedVersions;\n }\n\n cachedVersions = {\n core: fetchLatestVersion(\"@mcp-apps-kit/core\"),\n ui: fetchLatestVersion(\"@mcp-apps-kit/ui\"),\n uiReact: fetchLatestVersion(\"@mcp-apps-kit/ui-react\"),\n };\n\n return cachedVersions;\n}\n\n// =============================================================================\n// Template Content\n// =============================================================================\n\nfunction getReactTemplate(name: string, vercel = false): Record<string, string> {\n const uiOutputDir = vercel ? \"public\" : \"dist\";\n const packageManager = vercel ? \"npm\" : \"pnpm\";\n const versions = getPackageVersions();\n\n const files: Record<string, string> = {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: `concurrently \"${packageManager} run dev:server\" \"${packageManager} run dev:ui\"`,\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: `${packageManager} run build:ui && tsc`,\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": versions.core,\n \"@mcp-apps-kit/ui\": versions.ui,\n \"@mcp-apps-kit/ui-react\": versions.uiReact,\n react: \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n zod: \"^3.22.0\",\n ...(vercel ? { express: \"^4.21.0\" } : {}),\n },\n devDependencies: {\n \"@types/react\": \"^18.2.0\",\n \"@types/react-dom\": \"^18.2.0\",\n \"@vitejs/plugin-react\": \"^4.2.0\",\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n jsx: \"react-jsx\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": vercel\n ? `/**\n * ${name} - MCP Server\n */\n\n// Required for Vercel to detect Express\nimport \"express\";\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./${uiOutputDir}/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Only start locally - Vercel uses the exported Express app\nif (!process.env.VERCEL) {\n await app.start({ port: 3000 });\n console.log(\"MCP server running on http://localhost:3000\");\n}\n\n// Export Express app for Vercel\nexport default app.expressApp;\n`\n : `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/App.tsx\": `/**\n * ${name} - UI Component\n */\n\nimport {\n useAppsClient,\n useHostContext,\n useDocumentTheme,\n useHostStyleVariables,\n} from \"@mcp-apps-kit/ui-react\";\n\nexport function App() {\n const client = useAppsClient();\n const context = useHostContext();\n\n // Apply theme and host styles\n useDocumentTheme(\"light\", \"dark\");\n useHostStyleVariables();\n\n // Get tool output from client\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n\n return (\n <div className=\"container\">\n {output?.message ? (\n <div className=\"greeting\">\n <h1>{output.message}</h1>\n <p className=\"timestamp\">Sent at: {output.timestamp}</p>\n </div>\n ) : (\n <p className=\"waiting\">Waiting for greeting...</p>\n )}\n\n <button\n className=\"button\"\n onClick={() => client.sendFollowUpMessage(\"Please greet me again!\")}\n >\n Request New Greeting\n </button>\n\n <footer className=\"meta\">\n Theme: {context.theme} | Locale: {context.locale}\n </footer>\n </div>\n );\n}\n`,\n \"ui/src/main.tsx\": `/**\n * ${name} - UI Entry Point\n */\n\nimport React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { AppsProvider } from \"@mcp-apps-kit/ui-react\";\nimport { App } from \"./App\";\nimport \"./styles.css\";\n\nconst root = document.getElementById(\"root\");\nif (!root) throw new Error(\"Root element not found\");\n\ncreateRoot(root).render(\n <React.StrictMode>\n <AppsProvider>\n <App />\n </AppsProvider>\n </React.StrictMode>\n);\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [react(), viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"${uiOutputDir}\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\npublic/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\n${packageManager} install\n${packageManager} run dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\n${packageManager} run build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n${\n vercel\n ? `\n## Deploy to Vercel\n\nThis project is configured for Vercel deployment:\n\n\\`\\`\\`bash\nvercel deploy\n\\`\\`\\`\n\nThen use the deployed URL as your MCP server endpoint.\n`\n : \"\"\n}\n`,\n };\n\n // Add vercel.json if Vercel setup is enabled\n if (vercel) {\n files[\"vercel.json\"] = JSON.stringify(\n {\n installCommand: \"npm install\",\n buildCommand: \"npm run build:ui\",\n outputDirectory: \".\",\n functions: {\n \"server/index.ts\": {\n includeFiles: `${uiOutputDir}/**`,\n },\n },\n rewrites: [\n {\n source: \"/(.*)\",\n destination: \"/server/index.ts\",\n },\n ],\n },\n null,\n 2\n );\n }\n\n return files;\n}\n\nfunction getVanillaTemplate(name: string, vercel = false): Record<string, string> {\n const uiOutputDir = vercel ? \"public\" : \"dist\";\n const packageManager = vercel ? \"npm\" : \"pnpm\";\n const versions = getPackageVersions();\n\n const files: Record<string, string> = {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: `concurrently \"${packageManager} run dev:server\" \"${packageManager} run dev:ui\"`,\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: `${packageManager} run build:ui && tsc`,\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": versions.core,\n \"@mcp-apps-kit/ui\": versions.ui,\n zod: \"^3.22.0\",\n ...(vercel ? { express: \"^4.21.0\" } : {}),\n },\n devDependencies: {\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": vercel\n ? `/**\n * ${name} - MCP Server\n */\n\n// Required for Vercel to detect Express\nimport \"express\";\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./${uiOutputDir}/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Only start locally - Vercel uses the exported Express app\nif (!process.env.VERCEL) {\n await app.start({ port: 3000 });\n console.log(\"MCP server running on http://localhost:3000\");\n}\n\n// Export Express app for Vercel\nexport default app.expressApp;\n`\n : `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/main.ts\": `/**\n * ${name} - UI Entry Point\n */\n\nimport { createClient } from \"@mcp-apps-kit/ui\";\nimport \"./styles.css\";\n\nasync function main() {\n const client = await createClient();\n\n // Get container\n const container = document.getElementById(\"app\");\n if (!container) throw new Error(\"Container not found\");\n\n // Render initial UI\n render(container, client);\n\n // Subscribe to context changes\n client.onHostContextChange((context) => {\n document.documentElement.className = context.theme;\n render(container, client);\n });\n}\n\nfunction render(container: HTMLElement, client: ReturnType<typeof createClient> extends Promise<infer T> ? T : never) {\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n const context = client.hostContext;\n\n container.innerHTML = \\`\n <div class=\"container\">\n \\${output?.message ? \\`\n <div class=\"greeting\">\n <h1>\\${output.message}</h1>\n <p class=\"timestamp\">Sent at: \\${output.timestamp}</p>\n </div>\n \\` : \\`\n <p class=\"waiting\">Waiting for greeting...</p>\n \\`}\n\n <button class=\"button\" id=\"request-btn\">\n Request New Greeting\n </button>\n\n <footer class=\"meta\">\n Theme: \\${context.theme} | Locale: \\${context.locale}\n </footer>\n </div>\n \\`;\n\n // Add event listener\n const btn = document.getElementById(\"request-btn\");\n btn?.addEventListener(\"click\", () => {\n client.sendFollowUpMessage(\"Please greet me again!\");\n });\n}\n\nmain();\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.ts\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"${uiOutputDir}\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\npublic/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\n${packageManager} install\n${packageManager} run dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\n${packageManager} run build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n${\n vercel\n ? `\n## Deploy to Vercel\n\nThis project is configured for Vercel deployment:\n\n\\`\\`\\`bash\nvercel deploy\n\\`\\`\\`\n\nThen use the deployed URL as your MCP server endpoint.\n`\n : \"\"\n}\n`,\n };\n\n // Add vercel.json if Vercel setup is enabled\n if (vercel) {\n files[\"vercel.json\"] = JSON.stringify(\n {\n installCommand: \"npm install\",\n buildCommand: \"npm run build:ui\",\n outputDirectory: \".\",\n functions: {\n \"server/index.ts\": {\n includeFiles: `${uiOutputDir}/**`,\n },\n },\n rewrites: [\n {\n source: \"/(.*)\",\n destination: \"/server/index.ts\",\n },\n ],\n },\n null,\n 2\n );\n }\n\n return files;\n}\n\n// =============================================================================\n// Scaffolding Logic\n// =============================================================================\n\n/**\n * Scaffold a new MCP application project\n */\nexport async function scaffoldProject(options: CreateAppOptions): Promise<void> {\n const {\n name,\n template,\n directory,\n vercel = false,\n skipInstall = false,\n skipGit = false,\n } = options;\n\n // Determine project directory\n const projectDir = directory ?? path.resolve(process.cwd(), name);\n\n // Check if directory exists and is not empty\n if (fs.existsSync(projectDir)) {\n const files = fs.readdirSync(projectDir);\n if (files.length > 0) {\n throw new Error(`Directory ${projectDir} is not empty. Please use an empty directory.`);\n }\n } else {\n fs.mkdirSync(projectDir, { recursive: true });\n }\n\n // Get template files\n const templateFiles =\n template === \"react\" ? getReactTemplate(name, vercel) : getVanillaTemplate(name, vercel);\n\n // Write all files\n for (const [filePath, content] of Object.entries(templateFiles)) {\n const fullPath = path.join(projectDir, filePath);\n const dir = path.dirname(fullPath);\n\n // Create directory if needed\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n fs.writeFileSync(fullPath, content, \"utf-8\");\n }\n\n // Initialize git repository\n if (!skipGit) {\n try {\n execSync(\"git init\", { cwd: projectDir, stdio: \"ignore\" });\n } catch {\n // Ignore git init errors (git may not be installed)\n }\n }\n\n // Install dependencies\n if (!skipInstall) {\n try {\n if (vercel) {\n // Use npm for Vercel projects (better compatibility)\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n } else {\n // Try pnpm first, fall back to npm\n try {\n execSync(\"pnpm install\", { cwd: projectDir, stdio: \"inherit\" });\n } catch {\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n }\n }\n } catch {\n // eslint-disable-next-line no-console\n console.warn(\"Warning: Could not install dependencies automatically.\");\n }\n }\n}\n","/**\n * @mcp-apps-kit/create-app CLI\n *\n * Command-line interface for scaffolding MCP applications.\n */\n/* eslint-disable no-console */\n\nimport { Command, InvalidArgumentError } from \"commander\";\nimport prompts from \"prompts\";\nimport chalk from \"chalk\";\nimport { scaffoldProject } from \"./index.js\";\nimport type { CreateAppOptions } from \"./index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CLIOptions {\n name?: string;\n template: \"react\" | \"vanilla\";\n directory?: string;\n skipInstall: boolean;\n skipGit: boolean;\n vercel: boolean;\n interactive: boolean;\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\n/**\n * Validate a project name follows npm package naming conventions\n */\nexport function validateProjectName(name: string): boolean {\n if (!name || name.length === 0) {\n return false;\n }\n\n // Check for scoped packages\n if (name.startsWith(\"@\")) {\n const parts = name.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) return false;\n const scope = parts[0].slice(1);\n const pkg = parts[1];\n return validateSimpleName(scope) && validateSimpleName(pkg);\n }\n\n return validateSimpleName(name);\n}\n\nfunction validateSimpleName(name: string): boolean {\n // npm package name rules:\n // - lowercase\n // - one word (no spaces)\n // - can contain hyphens, underscores, dots\n // - cannot start with dot or underscore\n const validPattern = /^[a-z][a-z0-9._-]*$/;\n return validPattern.test(name);\n}\n\n// =============================================================================\n// Argument Parsing\n// =============================================================================\n\nconst VALID_TEMPLATES = [\"react\", \"vanilla\"] as const;\ntype Template = (typeof VALID_TEMPLATES)[number];\n\n/**\n * Parse CLI arguments\n */\nexport function parseArgs(args: string[]): CLIOptions {\n let result: CLIOptions = {\n template: \"react\",\n skipInstall: false,\n skipGit: false,\n vercel: false,\n interactive: false,\n };\n\n const program = new Command()\n .name(\"create-mcp-apps-kit\")\n .description(\"Scaffold a new MCP application\")\n .version(\"0.1.0\")\n .argument(\"[name]\", \"Project name\")\n .option(\n \"-t, --template <template>\",\n \"Template to use (react, vanilla)\",\n (value) => {\n if (!VALID_TEMPLATES.includes(value as Template)) {\n throw new InvalidArgumentError(\n `Invalid template: ${value}. Must be one of: ${VALID_TEMPLATES.join(\", \")}`\n );\n }\n return value as Template;\n },\n \"react\"\n )\n .option(\"-d, --directory <path>\", \"Directory to create project in\")\n .option(\"--skip-install\", \"Skip installing dependencies\", false)\n .option(\"--skip-git\", \"Skip initializing git repository\", false)\n .option(\"--vercel\", \"Add Vercel deployment configuration\", false)\n .allowUnknownOption(false)\n .parse([\"node\", \"create-mcp-apps-kit\", ...args]);\n\n const options = program.opts<{\n template: Template;\n directory?: string;\n skipInstall: boolean;\n skipGit: boolean;\n vercel: boolean;\n }>();\n const [name] = program.args;\n\n result = {\n name,\n template: options.template,\n directory: options.directory,\n skipInstall: options.skipInstall,\n skipGit: options.skipGit,\n vercel: options.vercel,\n interactive: !name,\n };\n\n return result;\n}\n\n// =============================================================================\n// Interactive Mode\n// =============================================================================\n\nasync function runInteractive(): Promise<CreateAppOptions> {\n console.log();\n console.log(chalk.bold(\"🚀 Create a new MCP application\"));\n console.log();\n\n const response = await prompts<\"name\" | \"template\" | \"vercel\" | \"skipInstall\" | \"skipGit\">([\n {\n type: \"text\",\n name: \"name\",\n message: \"Project name:\",\n validate: (value: string) => {\n if (!validateProjectName(value)) {\n return \"Invalid project name. Must be lowercase, no spaces, valid npm package name.\";\n }\n return true;\n },\n },\n {\n type: \"select\",\n name: \"template\",\n message: \"Template:\",\n choices: [\n { title: \"React\", value: \"react\", description: \"React + TypeScript with hooks\" },\n { title: \"Vanilla\", value: \"vanilla\", description: \"Vanilla TypeScript\" },\n ],\n initial: 0,\n },\n {\n type: \"confirm\",\n name: \"vercel\",\n message: \"Add Vercel deployment setup?\",\n initial: true,\n },\n {\n type: \"confirm\",\n name: \"skipInstall\",\n message: \"Skip installing dependencies?\",\n initial: false,\n },\n {\n type: \"confirm\",\n name: \"skipGit\",\n message: \"Skip initializing git?\",\n initial: false,\n },\n ]);\n\n if (!response.name) {\n console.log(chalk.yellow(\"Cancelled.\"));\n process.exit(0);\n }\n\n return {\n name: response.name as string,\n template: response.template as \"react\" | \"vanilla\",\n vercel: response.vercel as boolean,\n skipInstall: response.skipInstall as boolean,\n skipGit: response.skipGit as boolean,\n };\n}\n\n// =============================================================================\n// Main Entry Point\n// =============================================================================\n\nasync function main(): Promise<void> {\n try {\n const cliOptions = parseArgs(process.argv.slice(2));\n\n let options: CreateAppOptions;\n\n if (cliOptions.interactive) {\n options = await runInteractive();\n } else {\n if (!cliOptions.name) {\n console.error(chalk.red(\"Error: Project name is required\"));\n process.exit(1);\n }\n\n if (!validateProjectName(cliOptions.name)) {\n console.error(chalk.red(\"Error: Invalid project name. Must be a valid npm package name.\"));\n process.exit(1);\n }\n\n options = {\n name: cliOptions.name,\n template: cliOptions.template,\n directory: cliOptions.directory,\n skipInstall: cliOptions.skipInstall,\n skipGit: cliOptions.skipGit,\n vercel: cliOptions.vercel,\n };\n }\n\n console.log();\n console.log(chalk.blue(`Creating ${options.name} with ${options.template} template...`));\n if (options.vercel) {\n console.log(chalk.blue(\"Setting up for Vercel deployment...\"));\n }\n console.log();\n\n await scaffoldProject(options);\n\n const packageManager = options.vercel ? \"npm\" : \"pnpm\";\n\n console.log();\n console.log(chalk.green(\"✓ Project created successfully!\"));\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.cyan(` cd ${options.directory ?? options.name}`));\n if (!options.skipInstall) {\n console.log(chalk.cyan(` ${packageManager} run dev`));\n } else {\n console.log(chalk.cyan(` ${packageManager} install`));\n console.log(chalk.cyan(` ${packageManager} run dev`));\n }\n if (options.vercel) {\n console.log();\n console.log(\"To deploy to Vercel:\");\n console.log(chalk.cyan(\" vercel deploy\"));\n }\n console.log();\n } catch (error) {\n console.error(chalk.red(\"Error:\"), error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n\n// Run if executed directly\nvoid main();\n"]}

@@ -29,4 +29,30 @@ 'use strict';

// src/index.ts
function getReactTemplate(name) {
return {
var cachedVersions = null;
function fetchLatestVersion(packageName) {
try {
const result = child_process.execSync(`npm view ${packageName} version`, {
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"]
}).trim();
return `^${result}`;
} catch {
return "^0.2.0";
}
}
function getPackageVersions() {
if (cachedVersions) {
return cachedVersions;
}
cachedVersions = {
core: fetchLatestVersion("@mcp-apps-kit/core"),
ui: fetchLatestVersion("@mcp-apps-kit/ui"),
uiReact: fetchLatestVersion("@mcp-apps-kit/ui-react")
};
return cachedVersions;
}
function getReactTemplate(name, vercel = false) {
const uiOutputDir = vercel ? "public" : "dist";
const packageManager = vercel ? "npm" : "pnpm";
const versions = getPackageVersions();
const files = {
"package.json": JSON.stringify(

@@ -38,6 +64,6 @@ {

scripts: {
dev: 'concurrently "pnpm dev:server" "pnpm dev:ui"',
dev: `concurrently "${packageManager} run dev:server" "${packageManager} run dev:ui"`,
"dev:server": "tsx watch server/index.ts",
"dev:ui": "vite --config ui/vite.config.ts",
build: "pnpm build:ui && tsc",
build: `${packageManager} run build:ui && tsc`,
"build:ui": "vite build --config ui/vite.config.ts",

@@ -47,8 +73,9 @@ start: "node dist/server/index.js"

dependencies: {
"@mcp-apps-kit/core": "^0.1.0",
"@mcp-apps-kit/ui": "^0.1.0",
"@mcp-apps-kit/ui-react": "^0.1.0",
"@mcp-apps-kit/core": versions.core,
"@mcp-apps-kit/ui": versions.ui,
"@mcp-apps-kit/ui-react": versions.uiReact,
react: "^18.2.0",
"react-dom": "^18.2.0",
zod: "^3.22.0"
zod: "^3.22.0",
...vercel ? { express: "^4.21.0" } : {}
},

@@ -88,6 +115,9 @@ devDependencies: {

),
"server/index.ts": `/**
"server/index.ts": vercel ? `/**
* ${name} - MCP Server
*/
// Required for Vercel to detect Express
import "express";
import { createApp } from "@mcp-apps-kit/core";

@@ -122,2 +152,50 @@ import { z } from "zod";

greeting: {
html: "./${uiOutputDir}/index.html",
description: "Greeting widget",
prefersBorder: true,
},
},
});
// Only start locally - Vercel uses the exported Express app
if (!process.env.VERCEL) {
await app.start({ port: 3000 });
console.log("MCP server running on http://localhost:3000");
}
// Export Express app for Vercel
export default app.expressApp;
` : `/**
* ${name} - MCP Server
*/
import { createApp } from "@mcp-apps-kit/core";
import { z } from "zod";
const app = createApp({
name: "${name}",
version: "0.1.0",
tools: {
hello: {
description: "Say hello to someone",
input: z.object({
name: z.string().describe("Name to greet"),
}),
output: z.object({
message: z.string(),
timestamp: z.string(),
}),
handler: async ({ name }) => {
return {
message: \`Hello, \${name}!\`,
timestamp: new Date().toISOString(),
};
},
ui: "greeting",
},
},
ui: {
greeting: {
html: "./ui/dist/index.html",

@@ -291,3 +369,3 @@ description: "Greeting widget",

build: {
outDir: "dist",
outDir: "${uiOutputDir}",
emptyOutDir: true,

@@ -299,2 +377,3 @@ },

dist/
public/
*.log

@@ -311,4 +390,4 @@ .env

\`\`\`bash
pnpm install
pnpm dev
${packageManager} install
${packageManager} run dev
\`\`\`

@@ -319,3 +398,3 @@

\`\`\`bash
pnpm build
${packageManager} run build
\`\`\`

@@ -337,7 +416,44 @@

\`\`\`
${vercel ? `
## Deploy to Vercel
This project is configured for Vercel deployment:
\`\`\`bash
vercel deploy
\`\`\`
Then use the deployed URL as your MCP server endpoint.
` : ""}
`
};
if (vercel) {
files["vercel.json"] = JSON.stringify(
{
installCommand: "npm install",
buildCommand: "npm run build:ui",
outputDirectory: ".",
functions: {
"server/index.ts": {
includeFiles: `${uiOutputDir}/**`
}
},
rewrites: [
{
source: "/(.*)",
destination: "/server/index.ts"
}
]
},
null,
2
);
}
return files;
}
function getVanillaTemplate(name) {
return {
function getVanillaTemplate(name, vercel = false) {
const uiOutputDir = vercel ? "public" : "dist";
const packageManager = vercel ? "npm" : "pnpm";
const versions = getPackageVersions();
const files = {
"package.json": JSON.stringify(

@@ -349,6 +465,6 @@ {

scripts: {
dev: 'concurrently "pnpm dev:server" "pnpm dev:ui"',
dev: `concurrently "${packageManager} run dev:server" "${packageManager} run dev:ui"`,
"dev:server": "tsx watch server/index.ts",
"dev:ui": "vite --config ui/vite.config.ts",
build: "pnpm build:ui && tsc",
build: `${packageManager} run build:ui && tsc`,
"build:ui": "vite build --config ui/vite.config.ts",

@@ -358,5 +474,6 @@ start: "node dist/server/index.js"

dependencies: {
"@mcp-apps-kit/core": "^0.1.0",
"@mcp-apps-kit/ui": "^0.1.0",
zod: "^3.22.0"
"@mcp-apps-kit/core": versions.core,
"@mcp-apps-kit/ui": versions.ui,
zod: "^3.22.0",
...vercel ? { express: "^4.21.0" } : {}
},

@@ -392,6 +509,9 @@ devDependencies: {

),
"server/index.ts": `/**
"server/index.ts": vercel ? `/**
* ${name} - MCP Server
*/
// Required for Vercel to detect Express
import "express";
import { createApp } from "@mcp-apps-kit/core";

@@ -426,2 +546,50 @@ import { z } from "zod";

greeting: {
html: "./${uiOutputDir}/index.html",
description: "Greeting widget",
prefersBorder: true,
},
},
});
// Only start locally - Vercel uses the exported Express app
if (!process.env.VERCEL) {
await app.start({ port: 3000 });
console.log("MCP server running on http://localhost:3000");
}
// Export Express app for Vercel
export default app.expressApp;
` : `/**
* ${name} - MCP Server
*/
import { createApp } from "@mcp-apps-kit/core";
import { z } from "zod";
const app = createApp({
name: "${name}",
version: "0.1.0",
tools: {
hello: {
description: "Say hello to someone",
input: z.object({
name: z.string().describe("Name to greet"),
}),
output: z.object({
message: z.string(),
timestamp: z.string(),
}),
handler: async ({ name }) => {
return {
message: \`Hello, \${name}!\`,
timestamp: new Date().toISOString(),
};
},
ui: "greeting",
},
},
ui: {
greeting: {
html: "./ui/dist/index.html",

@@ -584,3 +752,3 @@ description: "Greeting widget",

build: {
outDir: "dist",
outDir: "${uiOutputDir}",
emptyOutDir: true,

@@ -592,2 +760,3 @@ },

dist/
public/
*.log

@@ -604,4 +773,4 @@ .env

\`\`\`bash
pnpm install
pnpm dev
${packageManager} install
${packageManager} run dev
\`\`\`

@@ -612,3 +781,3 @@

\`\`\`bash
pnpm build
${packageManager} run build
\`\`\`

@@ -630,7 +799,48 @@

\`\`\`
${vercel ? `
## Deploy to Vercel
This project is configured for Vercel deployment:
\`\`\`bash
vercel deploy
\`\`\`
Then use the deployed URL as your MCP server endpoint.
` : ""}
`
};
if (vercel) {
files["vercel.json"] = JSON.stringify(
{
installCommand: "npm install",
buildCommand: "npm run build:ui",
outputDirectory: ".",
functions: {
"server/index.ts": {
includeFiles: `${uiOutputDir}/**`
}
},
rewrites: [
{
source: "/(.*)",
destination: "/server/index.ts"
}
]
},
null,
2
);
}
return files;
}
async function scaffoldProject(options) {
const { name, template, directory, skipInstall = false, skipGit = false } = options;
const {
name,
template,
directory,
vercel = false,
skipInstall = false,
skipGit = false
} = options;
const projectDir = directory ?? path__namespace.resolve(process.cwd(), name);

@@ -645,3 +855,3 @@ if (fs__namespace.existsSync(projectDir)) {

}
const templateFiles = template === "react" ? getReactTemplate(name) : getVanillaTemplate(name);
const templateFiles = template === "react" ? getReactTemplate(name, vercel) : getVanillaTemplate(name, vercel);
for (const [filePath, content] of Object.entries(templateFiles)) {

@@ -663,6 +873,10 @@ const fullPath = path__namespace.join(projectDir, filePath);

try {
try {
child_process.execSync("pnpm install", { cwd: projectDir, stdio: "inherit" });
} catch {
if (vercel) {
child_process.execSync("npm install", { cwd: projectDir, stdio: "inherit" });
} else {
try {
child_process.execSync("pnpm install", { cwd: projectDir, stdio: "inherit" });
} catch {
child_process.execSync("npm install", { cwd: projectDir, stdio: "inherit" });
}
}

@@ -669,0 +883,0 @@ } catch {

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/index.ts"],"names":["path","fs","execSync"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @mcp-apps-kit/create-app\n *\n * Project scaffolding for MCP applications.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CreateAppOptions {\n name: string;\n template: \"react\" | \"vanilla\";\n directory?: string;\n skipInstall?: boolean;\n skipGit?: boolean;\n}\n\n// =============================================================================\n// Template Content\n// =============================================================================\n\nfunction getReactTemplate(name: string): Record<string, string> {\n return {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: 'concurrently \"pnpm dev:server\" \"pnpm dev:ui\"',\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: \"pnpm build:ui && tsc\",\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": \"^0.1.0\",\n \"@mcp-apps-kit/ui\": \"^0.1.0\",\n \"@mcp-apps-kit/ui-react\": \"^0.1.0\",\n react: \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n zod: \"^3.22.0\",\n },\n devDependencies: {\n \"@types/react\": \"^18.2.0\",\n \"@types/react-dom\": \"^18.2.0\",\n \"@vitejs/plugin-react\": \"^4.2.0\",\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n jsx: \"react-jsx\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/App.tsx\": `/**\n * ${name} - UI Component\n */\n\nimport {\n useAppsClient,\n useHostContext,\n useDocumentTheme,\n useHostStyleVariables,\n} from \"@mcp-apps-kit/ui-react\";\n\nexport function App() {\n const client = useAppsClient();\n const context = useHostContext();\n\n // Apply theme and host styles\n useDocumentTheme(\"light\", \"dark\");\n useHostStyleVariables();\n\n // Get tool output from client\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n\n return (\n <div className=\"container\">\n {output?.message ? (\n <div className=\"greeting\">\n <h1>{output.message}</h1>\n <p className=\"timestamp\">Sent at: {output.timestamp}</p>\n </div>\n ) : (\n <p className=\"waiting\">Waiting for greeting...</p>\n )}\n\n <button\n className=\"button\"\n onClick={() => client.sendFollowUpMessage(\"Please greet me again!\")}\n >\n Request New Greeting\n </button>\n\n <footer className=\"meta\">\n Theme: {context.theme} | Locale: {context.locale}\n </footer>\n </div>\n );\n}\n`,\n \"ui/src/main.tsx\": `/**\n * ${name} - UI Entry Point\n */\n\nimport React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { AppsProvider } from \"@mcp-apps-kit/ui-react\";\nimport { App } from \"./App\";\nimport \"./styles.css\";\n\nconst root = document.getElementById(\"root\");\nif (!root) throw new Error(\"Root element not found\");\n\ncreateRoot(root).render(\n <React.StrictMode>\n <AppsProvider>\n <App />\n </AppsProvider>\n </React.StrictMode>\n);\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [react(), viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"dist\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\npnpm install\npnpm dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\npnpm build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n`,\n };\n}\n\nfunction getVanillaTemplate(name: string): Record<string, string> {\n return {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: 'concurrently \"pnpm dev:server\" \"pnpm dev:ui\"',\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: \"pnpm build:ui && tsc\",\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": \"^0.1.0\",\n \"@mcp-apps-kit/ui\": \"^0.1.0\",\n zod: \"^3.22.0\",\n },\n devDependencies: {\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/main.ts\": `/**\n * ${name} - UI Entry Point\n */\n\nimport { createClient } from \"@mcp-apps-kit/ui\";\nimport \"./styles.css\";\n\nasync function main() {\n const client = await createClient();\n\n // Get container\n const container = document.getElementById(\"app\");\n if (!container) throw new Error(\"Container not found\");\n\n // Render initial UI\n render(container, client);\n\n // Subscribe to context changes\n client.onHostContextChange((context) => {\n document.documentElement.className = context.theme;\n render(container, client);\n });\n}\n\nfunction render(container: HTMLElement, client: ReturnType<typeof createClient> extends Promise<infer T> ? T : never) {\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n const context = client.hostContext;\n\n container.innerHTML = \\`\n <div class=\"container\">\n \\${output?.message ? \\`\n <div class=\"greeting\">\n <h1>\\${output.message}</h1>\n <p class=\"timestamp\">Sent at: \\${output.timestamp}</p>\n </div>\n \\` : \\`\n <p class=\"waiting\">Waiting for greeting...</p>\n \\`}\n\n <button class=\"button\" id=\"request-btn\">\n Request New Greeting\n </button>\n\n <footer class=\"meta\">\n Theme: \\${context.theme} | Locale: \\${context.locale}\n </footer>\n </div>\n \\`;\n\n // Add event listener\n const btn = document.getElementById(\"request-btn\");\n btn?.addEventListener(\"click\", () => {\n client.sendFollowUpMessage(\"Please greet me again!\");\n });\n}\n\nmain();\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.ts\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"dist\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\npnpm install\npnpm dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\npnpm build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n`,\n };\n}\n\n// =============================================================================\n// Scaffolding Logic\n// =============================================================================\n\n/**\n * Scaffold a new MCP application project\n */\nexport async function scaffoldProject(options: CreateAppOptions): Promise<void> {\n const { name, template, directory, skipInstall = false, skipGit = false } = options;\n\n // Determine project directory\n const projectDir = directory ?? path.resolve(process.cwd(), name);\n\n // Check if directory exists and is not empty\n if (fs.existsSync(projectDir)) {\n const files = fs.readdirSync(projectDir);\n if (files.length > 0) {\n throw new Error(`Directory ${projectDir} is not empty. Please use an empty directory.`);\n }\n } else {\n fs.mkdirSync(projectDir, { recursive: true });\n }\n\n // Get template files\n const templateFiles = template === \"react\" ? getReactTemplate(name) : getVanillaTemplate(name);\n\n // Write all files\n for (const [filePath, content] of Object.entries(templateFiles)) {\n const fullPath = path.join(projectDir, filePath);\n const dir = path.dirname(fullPath);\n\n // Create directory if needed\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n fs.writeFileSync(fullPath, content, \"utf-8\");\n }\n\n // Initialize git repository\n if (!skipGit) {\n try {\n execSync(\"git init\", { cwd: projectDir, stdio: \"ignore\" });\n } catch {\n // Ignore git init errors (git may not be installed)\n }\n }\n\n // Install dependencies\n if (!skipInstall) {\n try {\n // Try pnpm first, fall back to npm\n try {\n execSync(\"pnpm install\", { cwd: projectDir, stdio: \"inherit\" });\n } catch {\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n }\n } catch {\n // eslint-disable-next-line no-console\n console.warn(\"Warning: Could not install dependencies automatically.\");\n }\n }\n}\n"]}
{"version":3,"sources":["../src/index.ts"],"names":["execSync","path","fs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,IAAI,cAAA,GAAyC,IAAA;AAK7C,SAAS,mBAAmB,WAAA,EAA6B;AACvD,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAASA,sBAAA,CAAS,CAAA,SAAA,EAAY,WAAW,CAAA,QAAA,CAAA,EAAY;AAAA,MACzD,QAAA,EAAU,OAAA;AAAA,MACV,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM;AAAA,KAC/B,EAAE,IAAA,EAAK;AACR,IAAA,OAAO,IAAI,MAAM,CAAA,CAAA;AAAA,EACnB,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,QAAA;AAAA,EACT;AACF;AAKA,SAAS,kBAAA,GAAsC;AAC7C,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,OAAO,cAAA;AAAA,EACT;AAEA,EAAA,cAAA,GAAiB;AAAA,IACf,IAAA,EAAM,mBAAmB,oBAAoB,CAAA;AAAA,IAC7C,EAAA,EAAI,mBAAmB,kBAAkB,CAAA;AAAA,IACzC,OAAA,EAAS,mBAAmB,wBAAwB;AAAA,GACtD;AAEA,EAAA,OAAO,cAAA;AACT;AAMA,SAAS,gBAAA,CAAiB,IAAA,EAAc,MAAA,GAAS,KAAA,EAA+B;AAC9E,EAAA,MAAM,WAAA,GAAc,SAAS,QAAA,GAAW,MAAA;AACxC,EAAA,MAAM,cAAA,GAAiB,SAAS,KAAA,GAAQ,MAAA;AACxC,EAAA,MAAM,WAAW,kBAAA,EAAmB;AAEpC,EAAA,MAAM,KAAA,GAAgC;AAAA,IACpC,gBAAgB,IAAA,CAAK,SAAA;AAAA,MACnB;AAAA,QACE,IAAA;AAAA,QACA,OAAA,EAAS,OAAA;AAAA,QACT,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS;AAAA,UACP,GAAA,EAAK,CAAA,cAAA,EAAiB,cAAc,CAAA,kBAAA,EAAqB,cAAc,CAAA,YAAA,CAAA;AAAA,UACvE,YAAA,EAAc,2BAAA;AAAA,UACd,QAAA,EAAU,iCAAA;AAAA,UACV,KAAA,EAAO,GAAG,cAAc,CAAA,oBAAA,CAAA;AAAA,UACxB,UAAA,EAAY,uCAAA;AAAA,UACZ,KAAA,EAAO;AAAA,SACT;AAAA,QACA,YAAA,EAAc;AAAA,UACZ,sBAAsB,QAAA,CAAS,IAAA;AAAA,UAC/B,oBAAoB,QAAA,CAAS,EAAA;AAAA,UAC7B,0BAA0B,QAAA,CAAS,OAAA;AAAA,UACnC,KAAA,EAAO,SAAA;AAAA,UACP,WAAA,EAAa,SAAA;AAAA,UACb,GAAA,EAAK,SAAA;AAAA,UACL,GAAI,MAAA,GAAS,EAAE,OAAA,EAAS,SAAA,KAAc;AAAC,SACzC;AAAA,QACA,eAAA,EAAiB;AAAA,UACf,cAAA,EAAgB,SAAA;AAAA,UAChB,kBAAA,EAAoB,SAAA;AAAA,UACpB,sBAAA,EAAwB,QAAA;AAAA,UACxB,YAAA,EAAc,QAAA;AAAA,UACd,GAAA,EAAK,QAAA;AAAA,UACL,UAAA,EAAY,QAAA;AAAA,UACZ,IAAA,EAAM,QAAA;AAAA,UACN,wBAAA,EAA0B;AAAA;AAC5B,OACF;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,iBAAiB,IAAA,CAAK,SAAA;AAAA,MACpB;AAAA,QACE,eAAA,EAAiB;AAAA,UACf,MAAA,EAAQ,QAAA;AAAA,UACR,MAAA,EAAQ,QAAA;AAAA,UACR,gBAAA,EAAkB,SAAA;AAAA,UAClB,MAAA,EAAQ,IAAA;AAAA,UACR,eAAA,EAAiB,IAAA;AAAA,UACjB,YAAA,EAAc,IAAA;AAAA,UACd,WAAA,EAAa,IAAA;AAAA,UACb,MAAA,EAAQ,MAAA;AAAA,UACR,GAAA,EAAK;AAAA,SACP;AAAA,QACA,OAAA,EAAS,CAAC,aAAA,EAAe,aAAa,CAAA;AAAA,QACtC,OAAA,EAAS,CAAC,cAAA,EAAgB,MAAM;AAAA,OAClC;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,mBAAmB,MAAA,GACf,CAAA;AAAA,GAAA,EACH,IAAI,CAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,SAAA,EAUE,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,eAAA,EAyBE,WAAW,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA,GAgBpB,CAAA;AAAA,GAAA,EACH,IAAI,CAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,SAAA,EAOE,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoCX,gBAAA,EAAkB,CAAA;AAAA,GAAA,EACjB,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IA8CL,iBAAA,EAAmB,CAAA;AAAA,GAAA,EAClB,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoBL,mBAAA,EAAqB,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoErB,eAAA,EAAiB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAAA,EAKR,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAQb,mBAAA,EAAqB,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,aAAA,EAQV,WAAW,CAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAKtB,YAAA,EAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAOd,WAAA,EAAa,KAAK,IAAI;;AAAA;;AAAA;;AAAA;AAAA,EAOxB,cAAc,CAAA;AAAA,EACd,cAAc,CAAA;AAAA;;AAAA;;AAAA;AAAA,EAMd,cAAc,CAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA,KAAA,EAUT,IAAI,CAAA;AAAA;AAAA,+BAAA,EAEsB,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnC,MAAA,GACI;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA,CAAA,GAWA,EACN;AAAA;AAAA,GAEE;AAGA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,KAAA,CAAM,aAAa,IAAI,IAAA,CAAK,SAAA;AAAA,MAC1B;AAAA,QACE,cAAA,EAAgB,aAAA;AAAA,QAChB,YAAA,EAAc,kBAAA;AAAA,QACd,eAAA,EAAiB,GAAA;AAAA,QACjB,SAAA,EAAW;AAAA,UACT,iBAAA,EAAmB;AAAA,YACjB,YAAA,EAAc,GAAG,WAAW,CAAA,GAAA;AAAA;AAC9B,SACF;AAAA,QACA,QAAA,EAAU;AAAA,UACR;AAAA,YACE,MAAA,EAAQ,OAAA;AAAA,YACR,WAAA,EAAa;AAAA;AACf;AACF,OACF;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,kBAAA,CAAmB,IAAA,EAAc,MAAA,GAAS,KAAA,EAA+B;AAChF,EAAA,MAAM,WAAA,GAAc,SAAS,QAAA,GAAW,MAAA;AACxC,EAAA,MAAM,cAAA,GAAiB,SAAS,KAAA,GAAQ,MAAA;AACxC,EAAA,MAAM,WAAW,kBAAA,EAAmB;AAEpC,EAAA,MAAM,KAAA,GAAgC;AAAA,IACpC,gBAAgB,IAAA,CAAK,SAAA;AAAA,MACnB;AAAA,QACE,IAAA;AAAA,QACA,OAAA,EAAS,OAAA;AAAA,QACT,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS;AAAA,UACP,GAAA,EAAK,CAAA,cAAA,EAAiB,cAAc,CAAA,kBAAA,EAAqB,cAAc,CAAA,YAAA,CAAA;AAAA,UACvE,YAAA,EAAc,2BAAA;AAAA,UACd,QAAA,EAAU,iCAAA;AAAA,UACV,KAAA,EAAO,GAAG,cAAc,CAAA,oBAAA,CAAA;AAAA,UACxB,UAAA,EAAY,uCAAA;AAAA,UACZ,KAAA,EAAO;AAAA,SACT;AAAA,QACA,YAAA,EAAc;AAAA,UACZ,sBAAsB,QAAA,CAAS,IAAA;AAAA,UAC/B,oBAAoB,QAAA,CAAS,EAAA;AAAA,UAC7B,GAAA,EAAK,SAAA;AAAA,UACL,GAAI,MAAA,GAAS,EAAE,OAAA,EAAS,SAAA,KAAc;AAAC,SACzC;AAAA,QACA,eAAA,EAAiB;AAAA,UACf,YAAA,EAAc,QAAA;AAAA,UACd,GAAA,EAAK,QAAA;AAAA,UACL,UAAA,EAAY,QAAA;AAAA,UACZ,IAAA,EAAM,QAAA;AAAA,UACN,wBAAA,EAA0B;AAAA;AAC5B,OACF;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,iBAAiB,IAAA,CAAK,SAAA;AAAA,MACpB;AAAA,QACE,eAAA,EAAiB;AAAA,UACf,MAAA,EAAQ,QAAA;AAAA,UACR,MAAA,EAAQ,QAAA;AAAA,UACR,gBAAA,EAAkB,SAAA;AAAA,UAClB,MAAA,EAAQ,IAAA;AAAA,UACR,eAAA,EAAiB,IAAA;AAAA,UACjB,YAAA,EAAc,IAAA;AAAA,UACd,WAAA,EAAa,IAAA;AAAA,UACb,MAAA,EAAQ;AAAA,SACV;AAAA,QACA,OAAA,EAAS,CAAC,aAAA,EAAe,aAAa,CAAA;AAAA,QACtC,OAAA,EAAS,CAAC,cAAA,EAAgB,MAAM;AAAA,OAClC;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,mBAAmB,MAAA,GACf,CAAA;AAAA,GAAA,EACH,IAAI,CAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,SAAA,EAUE,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,eAAA,EAyBE,WAAW,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,CAAA,GAgBpB,CAAA;AAAA,GAAA,EACH,IAAI,CAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,SAAA,EAOE,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoCX,gBAAA,EAAkB,CAAA;AAAA,GAAA,EACjB,IAAI,CAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,CAAA;AAAA,IAyDL,mBAAA,EAAqB,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoErB,eAAA,EAAiB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAAA,EAKR,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAQb,mBAAA,EAAqB,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,aAAA,EAOV,WAAW,CAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAKtB,YAAA,EAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAOd,WAAA,EAAa,KAAK,IAAI;;AAAA;;AAAA;;AAAA;AAAA,EAOxB,cAAc,CAAA;AAAA,EACd,cAAc,CAAA;AAAA;;AAAA;;AAAA;AAAA,EAMd,cAAc,CAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA,KAAA,EAUT,IAAI,CAAA;AAAA;AAAA,+BAAA,EAEsB,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnC,MAAA,GACI;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA,CAAA,GAWA,EACN;AAAA;AAAA,GAEE;AAGA,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,KAAA,CAAM,aAAa,IAAI,IAAA,CAAK,SAAA;AAAA,MAC1B;AAAA,QACE,cAAA,EAAgB,aAAA;AAAA,QAChB,YAAA,EAAc,kBAAA;AAAA,QACd,eAAA,EAAiB,GAAA;AAAA,QACjB,SAAA,EAAW;AAAA,UACT,iBAAA,EAAmB;AAAA,YACjB,YAAA,EAAc,GAAG,WAAW,CAAA,GAAA;AAAA;AAC9B,SACF;AAAA,QACA,QAAA,EAAU;AAAA,UACR;AAAA,YACE,MAAA,EAAQ,OAAA;AAAA,YACR,WAAA,EAAa;AAAA;AACf;AACF,OACF;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AASA,eAAsB,gBAAgB,OAAA,EAA0C;AAC9E,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA,GAAS,KAAA;AAAA,IACT,WAAA,GAAc,KAAA;AAAA,IACd,OAAA,GAAU;AAAA,GACZ,GAAI,OAAA;AAGJ,EAAA,MAAM,aAAa,SAAA,IAAkBC,eAAA,CAAA,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,IAAI,CAAA;AAGhE,EAAA,IAAOC,aAAA,CAAA,UAAA,CAAW,UAAU,CAAA,EAAG;AAC7B,IAAA,MAAM,KAAA,GAAWA,0BAAY,UAAU,CAAA;AACvC,IAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,UAAA,EAAa,UAAU,CAAA,6CAAA,CAA+C,CAAA;AAAA,IACxF;AAAA,EACF,CAAA,MAAO;AACL,IAAGA,aAAA,CAAA,SAAA,CAAU,UAAA,EAAY,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,EAC9C;AAGA,EAAA,MAAM,aAAA,GACJ,aAAa,OAAA,GAAU,gBAAA,CAAiB,MAAM,MAAM,CAAA,GAAI,kBAAA,CAAmB,IAAA,EAAM,MAAM,CAAA;AAGzF,EAAA,KAAA,MAAW,CAAC,QAAA,EAAU,OAAO,KAAK,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAA,EAAG;AAC/D,IAAA,MAAM,QAAA,GAAgBD,eAAA,CAAA,IAAA,CAAK,UAAA,EAAY,QAAQ,CAAA;AAC/C,IAAA,MAAM,GAAA,GAAWA,wBAAQ,QAAQ,CAAA;AAGjC,IAAA,IAAI,CAAIC,aAAA,CAAA,UAAA,CAAW,GAAG,CAAA,EAAG;AACvB,MAAGA,aAAA,CAAA,SAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,IACvC;AAGA,IAAGA,aAAA,CAAA,aAAA,CAAc,QAAA,EAAU,OAAA,EAAS,OAAO,CAAA;AAAA,EAC7C;AAGA,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,IAAI;AACF,MAAAF,sBAAA,CAAS,YAAY,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,UAAU,CAAA;AAAA,IAC3D,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,IAAI;AACF,MAAA,IAAI,MAAA,EAAQ;AAEV,QAAAA,sBAAA,CAAS,eAAe,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,WAAW,CAAA;AAAA,MAC/D,CAAA,MAAO;AAEL,QAAA,IAAI;AACF,UAAAA,sBAAA,CAAS,gBAAgB,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,WAAW,CAAA;AAAA,QAChE,CAAA,CAAA,MAAQ;AACN,UAAAA,sBAAA,CAAS,eAAe,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,WAAW,CAAA;AAAA,QAC/D;AAAA,MACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAA,CAAQ,KAAK,wDAAwD,CAAA;AAAA,IACvE;AAAA,EACF;AACF","file":"index.cjs","sourcesContent":["/**\n * @mcp-apps-kit/create-app\n *\n * Project scaffolding for MCP applications.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CreateAppOptions {\n name: string;\n template: \"react\" | \"vanilla\";\n directory?: string;\n vercel?: boolean;\n skipInstall?: boolean;\n skipGit?: boolean;\n}\n\n// =============================================================================\n// Version Detection\n// =============================================================================\n\ninterface PackageVersions {\n core: string;\n ui: string;\n uiReact: string;\n}\n\n// Cache for fetched versions\nlet cachedVersions: PackageVersions | null = null;\n\n/**\n * Fetch the latest version of a package from npm registry\n */\nfunction fetchLatestVersion(packageName: string): string {\n try {\n const result = execSync(`npm view ${packageName} version`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n return `^${result}`;\n } catch {\n // Fallback to a reasonable default if we can't fetch\n return \"^0.2.0\";\n }\n}\n\n/**\n * Get the versions of @mcp-apps-kit packages from npm registry\n */\nfunction getPackageVersions(): PackageVersions {\n if (cachedVersions) {\n return cachedVersions;\n }\n\n cachedVersions = {\n core: fetchLatestVersion(\"@mcp-apps-kit/core\"),\n ui: fetchLatestVersion(\"@mcp-apps-kit/ui\"),\n uiReact: fetchLatestVersion(\"@mcp-apps-kit/ui-react\"),\n };\n\n return cachedVersions;\n}\n\n// =============================================================================\n// Template Content\n// =============================================================================\n\nfunction getReactTemplate(name: string, vercel = false): Record<string, string> {\n const uiOutputDir = vercel ? \"public\" : \"dist\";\n const packageManager = vercel ? \"npm\" : \"pnpm\";\n const versions = getPackageVersions();\n\n const files: Record<string, string> = {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: `concurrently \"${packageManager} run dev:server\" \"${packageManager} run dev:ui\"`,\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: `${packageManager} run build:ui && tsc`,\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": versions.core,\n \"@mcp-apps-kit/ui\": versions.ui,\n \"@mcp-apps-kit/ui-react\": versions.uiReact,\n react: \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n zod: \"^3.22.0\",\n ...(vercel ? { express: \"^4.21.0\" } : {}),\n },\n devDependencies: {\n \"@types/react\": \"^18.2.0\",\n \"@types/react-dom\": \"^18.2.0\",\n \"@vitejs/plugin-react\": \"^4.2.0\",\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n jsx: \"react-jsx\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": vercel\n ? `/**\n * ${name} - MCP Server\n */\n\n// Required for Vercel to detect Express\nimport \"express\";\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./${uiOutputDir}/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Only start locally - Vercel uses the exported Express app\nif (!process.env.VERCEL) {\n await app.start({ port: 3000 });\n console.log(\"MCP server running on http://localhost:3000\");\n}\n\n// Export Express app for Vercel\nexport default app.expressApp;\n`\n : `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/App.tsx\": `/**\n * ${name} - UI Component\n */\n\nimport {\n useAppsClient,\n useHostContext,\n useDocumentTheme,\n useHostStyleVariables,\n} from \"@mcp-apps-kit/ui-react\";\n\nexport function App() {\n const client = useAppsClient();\n const context = useHostContext();\n\n // Apply theme and host styles\n useDocumentTheme(\"light\", \"dark\");\n useHostStyleVariables();\n\n // Get tool output from client\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n\n return (\n <div className=\"container\">\n {output?.message ? (\n <div className=\"greeting\">\n <h1>{output.message}</h1>\n <p className=\"timestamp\">Sent at: {output.timestamp}</p>\n </div>\n ) : (\n <p className=\"waiting\">Waiting for greeting...</p>\n )}\n\n <button\n className=\"button\"\n onClick={() => client.sendFollowUpMessage(\"Please greet me again!\")}\n >\n Request New Greeting\n </button>\n\n <footer className=\"meta\">\n Theme: {context.theme} | Locale: {context.locale}\n </footer>\n </div>\n );\n}\n`,\n \"ui/src/main.tsx\": `/**\n * ${name} - UI Entry Point\n */\n\nimport React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { AppsProvider } from \"@mcp-apps-kit/ui-react\";\nimport { App } from \"./App\";\nimport \"./styles.css\";\n\nconst root = document.getElementById(\"root\");\nif (!root) throw new Error(\"Root element not found\");\n\ncreateRoot(root).render(\n <React.StrictMode>\n <AppsProvider>\n <App />\n </AppsProvider>\n </React.StrictMode>\n);\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [react(), viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"${uiOutputDir}\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\npublic/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\n${packageManager} install\n${packageManager} run dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\n${packageManager} run build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n${\n vercel\n ? `\n## Deploy to Vercel\n\nThis project is configured for Vercel deployment:\n\n\\`\\`\\`bash\nvercel deploy\n\\`\\`\\`\n\nThen use the deployed URL as your MCP server endpoint.\n`\n : \"\"\n}\n`,\n };\n\n // Add vercel.json if Vercel setup is enabled\n if (vercel) {\n files[\"vercel.json\"] = JSON.stringify(\n {\n installCommand: \"npm install\",\n buildCommand: \"npm run build:ui\",\n outputDirectory: \".\",\n functions: {\n \"server/index.ts\": {\n includeFiles: `${uiOutputDir}/**`,\n },\n },\n rewrites: [\n {\n source: \"/(.*)\",\n destination: \"/server/index.ts\",\n },\n ],\n },\n null,\n 2\n );\n }\n\n return files;\n}\n\nfunction getVanillaTemplate(name: string, vercel = false): Record<string, string> {\n const uiOutputDir = vercel ? \"public\" : \"dist\";\n const packageManager = vercel ? \"npm\" : \"pnpm\";\n const versions = getPackageVersions();\n\n const files: Record<string, string> = {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: `concurrently \"${packageManager} run dev:server\" \"${packageManager} run dev:ui\"`,\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: `${packageManager} run build:ui && tsc`,\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": versions.core,\n \"@mcp-apps-kit/ui\": versions.ui,\n zod: \"^3.22.0\",\n ...(vercel ? { express: \"^4.21.0\" } : {}),\n },\n devDependencies: {\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": vercel\n ? `/**\n * ${name} - MCP Server\n */\n\n// Required for Vercel to detect Express\nimport \"express\";\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./${uiOutputDir}/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Only start locally - Vercel uses the exported Express app\nif (!process.env.VERCEL) {\n await app.start({ port: 3000 });\n console.log(\"MCP server running on http://localhost:3000\");\n}\n\n// Export Express app for Vercel\nexport default app.expressApp;\n`\n : `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/main.ts\": `/**\n * ${name} - UI Entry Point\n */\n\nimport { createClient } from \"@mcp-apps-kit/ui\";\nimport \"./styles.css\";\n\nasync function main() {\n const client = await createClient();\n\n // Get container\n const container = document.getElementById(\"app\");\n if (!container) throw new Error(\"Container not found\");\n\n // Render initial UI\n render(container, client);\n\n // Subscribe to context changes\n client.onHostContextChange((context) => {\n document.documentElement.className = context.theme;\n render(container, client);\n });\n}\n\nfunction render(container: HTMLElement, client: ReturnType<typeof createClient> extends Promise<infer T> ? T : never) {\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n const context = client.hostContext;\n\n container.innerHTML = \\`\n <div class=\"container\">\n \\${output?.message ? \\`\n <div class=\"greeting\">\n <h1>\\${output.message}</h1>\n <p class=\"timestamp\">Sent at: \\${output.timestamp}</p>\n </div>\n \\` : \\`\n <p class=\"waiting\">Waiting for greeting...</p>\n \\`}\n\n <button class=\"button\" id=\"request-btn\">\n Request New Greeting\n </button>\n\n <footer class=\"meta\">\n Theme: \\${context.theme} | Locale: \\${context.locale}\n </footer>\n </div>\n \\`;\n\n // Add event listener\n const btn = document.getElementById(\"request-btn\");\n btn?.addEventListener(\"click\", () => {\n client.sendFollowUpMessage(\"Please greet me again!\");\n });\n}\n\nmain();\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.ts\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"${uiOutputDir}\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\npublic/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\n${packageManager} install\n${packageManager} run dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\n${packageManager} run build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n${\n vercel\n ? `\n## Deploy to Vercel\n\nThis project is configured for Vercel deployment:\n\n\\`\\`\\`bash\nvercel deploy\n\\`\\`\\`\n\nThen use the deployed URL as your MCP server endpoint.\n`\n : \"\"\n}\n`,\n };\n\n // Add vercel.json if Vercel setup is enabled\n if (vercel) {\n files[\"vercel.json\"] = JSON.stringify(\n {\n installCommand: \"npm install\",\n buildCommand: \"npm run build:ui\",\n outputDirectory: \".\",\n functions: {\n \"server/index.ts\": {\n includeFiles: `${uiOutputDir}/**`,\n },\n },\n rewrites: [\n {\n source: \"/(.*)\",\n destination: \"/server/index.ts\",\n },\n ],\n },\n null,\n 2\n );\n }\n\n return files;\n}\n\n// =============================================================================\n// Scaffolding Logic\n// =============================================================================\n\n/**\n * Scaffold a new MCP application project\n */\nexport async function scaffoldProject(options: CreateAppOptions): Promise<void> {\n const {\n name,\n template,\n directory,\n vercel = false,\n skipInstall = false,\n skipGit = false,\n } = options;\n\n // Determine project directory\n const projectDir = directory ?? path.resolve(process.cwd(), name);\n\n // Check if directory exists and is not empty\n if (fs.existsSync(projectDir)) {\n const files = fs.readdirSync(projectDir);\n if (files.length > 0) {\n throw new Error(`Directory ${projectDir} is not empty. Please use an empty directory.`);\n }\n } else {\n fs.mkdirSync(projectDir, { recursive: true });\n }\n\n // Get template files\n const templateFiles =\n template === \"react\" ? getReactTemplate(name, vercel) : getVanillaTemplate(name, vercel);\n\n // Write all files\n for (const [filePath, content] of Object.entries(templateFiles)) {\n const fullPath = path.join(projectDir, filePath);\n const dir = path.dirname(fullPath);\n\n // Create directory if needed\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n fs.writeFileSync(fullPath, content, \"utf-8\");\n }\n\n // Initialize git repository\n if (!skipGit) {\n try {\n execSync(\"git init\", { cwd: projectDir, stdio: \"ignore\" });\n } catch {\n // Ignore git init errors (git may not be installed)\n }\n }\n\n // Install dependencies\n if (!skipInstall) {\n try {\n if (vercel) {\n // Use npm for Vercel projects (better compatibility)\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n } else {\n // Try pnpm first, fall back to npm\n try {\n execSync(\"pnpm install\", { cwd: projectDir, stdio: \"inherit\" });\n } catch {\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n }\n }\n } catch {\n // eslint-disable-next-line no-console\n console.warn(\"Warning: Could not install dependencies automatically.\");\n }\n }\n}\n"]}

@@ -10,2 +10,3 @@ /**

directory?: string;
vercel?: boolean;
skipInstall?: boolean;

@@ -12,0 +13,0 @@ skipGit?: boolean;

@@ -10,2 +10,3 @@ /**

directory?: string;
vercel?: boolean;
skipInstall?: boolean;

@@ -12,0 +13,0 @@ skipGit?: boolean;

@@ -6,4 +6,30 @@ import * as fs from 'fs';

// src/index.ts
function getReactTemplate(name) {
return {
var cachedVersions = null;
function fetchLatestVersion(packageName) {
try {
const result = execSync(`npm view ${packageName} version`, {
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"]
}).trim();
return `^${result}`;
} catch {
return "^0.2.0";
}
}
function getPackageVersions() {
if (cachedVersions) {
return cachedVersions;
}
cachedVersions = {
core: fetchLatestVersion("@mcp-apps-kit/core"),
ui: fetchLatestVersion("@mcp-apps-kit/ui"),
uiReact: fetchLatestVersion("@mcp-apps-kit/ui-react")
};
return cachedVersions;
}
function getReactTemplate(name, vercel = false) {
const uiOutputDir = vercel ? "public" : "dist";
const packageManager = vercel ? "npm" : "pnpm";
const versions = getPackageVersions();
const files = {
"package.json": JSON.stringify(

@@ -15,6 +41,6 @@ {

scripts: {
dev: 'concurrently "pnpm dev:server" "pnpm dev:ui"',
dev: `concurrently "${packageManager} run dev:server" "${packageManager} run dev:ui"`,
"dev:server": "tsx watch server/index.ts",
"dev:ui": "vite --config ui/vite.config.ts",
build: "pnpm build:ui && tsc",
build: `${packageManager} run build:ui && tsc`,
"build:ui": "vite build --config ui/vite.config.ts",

@@ -24,8 +50,9 @@ start: "node dist/server/index.js"

dependencies: {
"@mcp-apps-kit/core": "^0.1.0",
"@mcp-apps-kit/ui": "^0.1.0",
"@mcp-apps-kit/ui-react": "^0.1.0",
"@mcp-apps-kit/core": versions.core,
"@mcp-apps-kit/ui": versions.ui,
"@mcp-apps-kit/ui-react": versions.uiReact,
react: "^18.2.0",
"react-dom": "^18.2.0",
zod: "^3.22.0"
zod: "^3.22.0",
...vercel ? { express: "^4.21.0" } : {}
},

@@ -65,6 +92,9 @@ devDependencies: {

),
"server/index.ts": `/**
"server/index.ts": vercel ? `/**
* ${name} - MCP Server
*/
// Required for Vercel to detect Express
import "express";
import { createApp } from "@mcp-apps-kit/core";

@@ -99,2 +129,50 @@ import { z } from "zod";

greeting: {
html: "./${uiOutputDir}/index.html",
description: "Greeting widget",
prefersBorder: true,
},
},
});
// Only start locally - Vercel uses the exported Express app
if (!process.env.VERCEL) {
await app.start({ port: 3000 });
console.log("MCP server running on http://localhost:3000");
}
// Export Express app for Vercel
export default app.expressApp;
` : `/**
* ${name} - MCP Server
*/
import { createApp } from "@mcp-apps-kit/core";
import { z } from "zod";
const app = createApp({
name: "${name}",
version: "0.1.0",
tools: {
hello: {
description: "Say hello to someone",
input: z.object({
name: z.string().describe("Name to greet"),
}),
output: z.object({
message: z.string(),
timestamp: z.string(),
}),
handler: async ({ name }) => {
return {
message: \`Hello, \${name}!\`,
timestamp: new Date().toISOString(),
};
},
ui: "greeting",
},
},
ui: {
greeting: {
html: "./ui/dist/index.html",

@@ -268,3 +346,3 @@ description: "Greeting widget",

build: {
outDir: "dist",
outDir: "${uiOutputDir}",
emptyOutDir: true,

@@ -276,2 +354,3 @@ },

dist/
public/
*.log

@@ -288,4 +367,4 @@ .env

\`\`\`bash
pnpm install
pnpm dev
${packageManager} install
${packageManager} run dev
\`\`\`

@@ -296,3 +375,3 @@

\`\`\`bash
pnpm build
${packageManager} run build
\`\`\`

@@ -314,7 +393,44 @@

\`\`\`
${vercel ? `
## Deploy to Vercel
This project is configured for Vercel deployment:
\`\`\`bash
vercel deploy
\`\`\`
Then use the deployed URL as your MCP server endpoint.
` : ""}
`
};
if (vercel) {
files["vercel.json"] = JSON.stringify(
{
installCommand: "npm install",
buildCommand: "npm run build:ui",
outputDirectory: ".",
functions: {
"server/index.ts": {
includeFiles: `${uiOutputDir}/**`
}
},
rewrites: [
{
source: "/(.*)",
destination: "/server/index.ts"
}
]
},
null,
2
);
}
return files;
}
function getVanillaTemplate(name) {
return {
function getVanillaTemplate(name, vercel = false) {
const uiOutputDir = vercel ? "public" : "dist";
const packageManager = vercel ? "npm" : "pnpm";
const versions = getPackageVersions();
const files = {
"package.json": JSON.stringify(

@@ -326,6 +442,6 @@ {

scripts: {
dev: 'concurrently "pnpm dev:server" "pnpm dev:ui"',
dev: `concurrently "${packageManager} run dev:server" "${packageManager} run dev:ui"`,
"dev:server": "tsx watch server/index.ts",
"dev:ui": "vite --config ui/vite.config.ts",
build: "pnpm build:ui && tsc",
build: `${packageManager} run build:ui && tsc`,
"build:ui": "vite build --config ui/vite.config.ts",

@@ -335,5 +451,6 @@ start: "node dist/server/index.js"

dependencies: {
"@mcp-apps-kit/core": "^0.1.0",
"@mcp-apps-kit/ui": "^0.1.0",
zod: "^3.22.0"
"@mcp-apps-kit/core": versions.core,
"@mcp-apps-kit/ui": versions.ui,
zod: "^3.22.0",
...vercel ? { express: "^4.21.0" } : {}
},

@@ -369,6 +486,9 @@ devDependencies: {

),
"server/index.ts": `/**
"server/index.ts": vercel ? `/**
* ${name} - MCP Server
*/
// Required for Vercel to detect Express
import "express";
import { createApp } from "@mcp-apps-kit/core";

@@ -403,2 +523,50 @@ import { z } from "zod";

greeting: {
html: "./${uiOutputDir}/index.html",
description: "Greeting widget",
prefersBorder: true,
},
},
});
// Only start locally - Vercel uses the exported Express app
if (!process.env.VERCEL) {
await app.start({ port: 3000 });
console.log("MCP server running on http://localhost:3000");
}
// Export Express app for Vercel
export default app.expressApp;
` : `/**
* ${name} - MCP Server
*/
import { createApp } from "@mcp-apps-kit/core";
import { z } from "zod";
const app = createApp({
name: "${name}",
version: "0.1.0",
tools: {
hello: {
description: "Say hello to someone",
input: z.object({
name: z.string().describe("Name to greet"),
}),
output: z.object({
message: z.string(),
timestamp: z.string(),
}),
handler: async ({ name }) => {
return {
message: \`Hello, \${name}!\`,
timestamp: new Date().toISOString(),
};
},
ui: "greeting",
},
},
ui: {
greeting: {
html: "./ui/dist/index.html",

@@ -561,3 +729,3 @@ description: "Greeting widget",

build: {
outDir: "dist",
outDir: "${uiOutputDir}",
emptyOutDir: true,

@@ -569,2 +737,3 @@ },

dist/
public/
*.log

@@ -581,4 +750,4 @@ .env

\`\`\`bash
pnpm install
pnpm dev
${packageManager} install
${packageManager} run dev
\`\`\`

@@ -589,3 +758,3 @@

\`\`\`bash
pnpm build
${packageManager} run build
\`\`\`

@@ -607,7 +776,48 @@

\`\`\`
${vercel ? `
## Deploy to Vercel
This project is configured for Vercel deployment:
\`\`\`bash
vercel deploy
\`\`\`
Then use the deployed URL as your MCP server endpoint.
` : ""}
`
};
if (vercel) {
files["vercel.json"] = JSON.stringify(
{
installCommand: "npm install",
buildCommand: "npm run build:ui",
outputDirectory: ".",
functions: {
"server/index.ts": {
includeFiles: `${uiOutputDir}/**`
}
},
rewrites: [
{
source: "/(.*)",
destination: "/server/index.ts"
}
]
},
null,
2
);
}
return files;
}
async function scaffoldProject(options) {
const { name, template, directory, skipInstall = false, skipGit = false } = options;
const {
name,
template,
directory,
vercel = false,
skipInstall = false,
skipGit = false
} = options;
const projectDir = directory ?? path.resolve(process.cwd(), name);

@@ -622,3 +832,3 @@ if (fs.existsSync(projectDir)) {

}
const templateFiles = template === "react" ? getReactTemplate(name) : getVanillaTemplate(name);
const templateFiles = template === "react" ? getReactTemplate(name, vercel) : getVanillaTemplate(name, vercel);
for (const [filePath, content] of Object.entries(templateFiles)) {

@@ -640,6 +850,10 @@ const fullPath = path.join(projectDir, filePath);

try {
try {
execSync("pnpm install", { cwd: projectDir, stdio: "inherit" });
} catch {
if (vercel) {
execSync("npm install", { cwd: projectDir, stdio: "inherit" });
} else {
try {
execSync("pnpm install", { cwd: projectDir, stdio: "inherit" });
} catch {
execSync("npm install", { cwd: projectDir, stdio: "inherit" });
}
}

@@ -646,0 +860,0 @@ } catch {

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;AA0BA,SAAS,iBAAiB,IAAA,EAAsC;AAC9D,EAAA,OAAO;AAAA,IACL,gBAAgB,IAAA,CAAK,SAAA;AAAA,MACnB;AAAA,QACE,IAAA;AAAA,QACA,OAAA,EAAS,OAAA;AAAA,QACT,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS;AAAA,UACP,GAAA,EAAK,8CAAA;AAAA,UACL,YAAA,EAAc,2BAAA;AAAA,UACd,QAAA,EAAU,iCAAA;AAAA,UACV,KAAA,EAAO,sBAAA;AAAA,UACP,UAAA,EAAY,uCAAA;AAAA,UACZ,KAAA,EAAO;AAAA,SACT;AAAA,QACA,YAAA,EAAc;AAAA,UACZ,oBAAA,EAAsB,QAAA;AAAA,UACtB,kBAAA,EAAoB,QAAA;AAAA,UACpB,wBAAA,EAA0B,QAAA;AAAA,UAC1B,KAAA,EAAO,SAAA;AAAA,UACP,WAAA,EAAa,SAAA;AAAA,UACb,GAAA,EAAK;AAAA,SACP;AAAA,QACA,eAAA,EAAiB;AAAA,UACf,cAAA,EAAgB,SAAA;AAAA,UAChB,kBAAA,EAAoB,SAAA;AAAA,UACpB,sBAAA,EAAwB,QAAA;AAAA,UACxB,YAAA,EAAc,QAAA;AAAA,UACd,GAAA,EAAK,QAAA;AAAA,UACL,UAAA,EAAY,QAAA;AAAA,UACZ,IAAA,EAAM,QAAA;AAAA,UACN,wBAAA,EAA0B;AAAA;AAC5B,OACF;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,iBAAiB,IAAA,CAAK,SAAA;AAAA,MACpB;AAAA,QACE,eAAA,EAAiB;AAAA,UACf,MAAA,EAAQ,QAAA;AAAA,UACR,MAAA,EAAQ,QAAA;AAAA,UACR,gBAAA,EAAkB,SAAA;AAAA,UAClB,MAAA,EAAQ,IAAA;AAAA,UACR,eAAA,EAAiB,IAAA;AAAA,UACjB,YAAA,EAAc,IAAA;AAAA,UACd,WAAA,EAAa,IAAA;AAAA,UACb,MAAA,EAAQ,MAAA;AAAA,UACR,GAAA,EAAK;AAAA,SACP;AAAA,QACA,OAAA,EAAS,CAAC,aAAA,EAAe,aAAa,CAAA;AAAA,QACtC,OAAA,EAAS,CAAC,cAAA,EAAgB,MAAM;AAAA,OAClC;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,iBAAA,EAAmB,CAAA;AAAA,GAAA,EAClB,IAAI,CAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,SAAA,EAOE,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoCX,gBAAA,EAAkB,CAAA;AAAA,GAAA,EACjB,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IA8CL,iBAAA,EAAmB,CAAA;AAAA,GAAA,EAClB,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoBL,mBAAA,EAAqB,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoErB,eAAA,EAAiB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAAA,EAKR,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAQb,mBAAA,EAAqB,CAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAarB,YAAA,EAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAMd,WAAA,EAAa,KAAK,IAAI;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA,KAAA,EAwBnB,IAAI,CAAA;AAAA;AAAA,+BAAA,EAEsB,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMnC;AACF;AAEA,SAAS,mBAAmB,IAAA,EAAsC;AAChE,EAAA,OAAO;AAAA,IACL,gBAAgB,IAAA,CAAK,SAAA;AAAA,MACnB;AAAA,QACE,IAAA;AAAA,QACA,OAAA,EAAS,OAAA;AAAA,QACT,IAAA,EAAM,QAAA;AAAA,QACN,OAAA,EAAS;AAAA,UACP,GAAA,EAAK,8CAAA;AAAA,UACL,YAAA,EAAc,2BAAA;AAAA,UACd,QAAA,EAAU,iCAAA;AAAA,UACV,KAAA,EAAO,sBAAA;AAAA,UACP,UAAA,EAAY,uCAAA;AAAA,UACZ,KAAA,EAAO;AAAA,SACT;AAAA,QACA,YAAA,EAAc;AAAA,UACZ,oBAAA,EAAsB,QAAA;AAAA,UACtB,kBAAA,EAAoB,QAAA;AAAA,UACpB,GAAA,EAAK;AAAA,SACP;AAAA,QACA,eAAA,EAAiB;AAAA,UACf,YAAA,EAAc,QAAA;AAAA,UACd,GAAA,EAAK,QAAA;AAAA,UACL,UAAA,EAAY,QAAA;AAAA,UACZ,IAAA,EAAM,QAAA;AAAA,UACN,wBAAA,EAA0B;AAAA;AAC5B,OACF;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,iBAAiB,IAAA,CAAK,SAAA;AAAA,MACpB;AAAA,QACE,eAAA,EAAiB;AAAA,UACf,MAAA,EAAQ,QAAA;AAAA,UACR,MAAA,EAAQ,QAAA;AAAA,UACR,gBAAA,EAAkB,SAAA;AAAA,UAClB,MAAA,EAAQ,IAAA;AAAA,UACR,eAAA,EAAiB,IAAA;AAAA,UACjB,YAAA,EAAc,IAAA;AAAA,UACd,WAAA,EAAa,IAAA;AAAA,UACb,MAAA,EAAQ;AAAA,SACV;AAAA,QACA,OAAA,EAAS,CAAC,aAAA,EAAe,aAAa,CAAA;AAAA,QACtC,OAAA,EAAS,CAAC,cAAA,EAAgB,MAAM;AAAA,OAClC;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,iBAAA,EAAmB,CAAA;AAAA,GAAA,EAClB,IAAI,CAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA,SAAA,EAOE,IAAI,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoCX,gBAAA,EAAkB,CAAA;AAAA,GAAA,EACjB,IAAI,CAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,CAAA;AAAA,IAyDL,mBAAA,EAAqB,CAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAoErB,eAAA,EAAiB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAAA,EAKR,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAQb,mBAAA,EAAqB,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAYrB,YAAA,EAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAAA,IAMd,WAAA,EAAa,KAAK,IAAI;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA,KAAA,EAwBnB,IAAI,CAAA;AAAA;AAAA,+BAAA,EAEsB,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAMnC;AACF;AASA,eAAsB,gBAAgB,OAAA,EAA0C;AAC9E,EAAA,MAAM,EAAE,MAAM,QAAA,EAAU,SAAA,EAAW,cAAc,KAAA,EAAO,OAAA,GAAU,OAAM,GAAI,OAAA;AAG5E,EAAA,MAAM,aAAa,SAAA,IAAkB,IAAA,CAAA,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,IAAI,CAAA;AAGhE,EAAA,IAAO,EAAA,CAAA,UAAA,CAAW,UAAU,CAAA,EAAG;AAC7B,IAAA,MAAM,KAAA,GAAW,eAAY,UAAU,CAAA;AACvC,IAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACpB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,UAAA,EAAa,UAAU,CAAA,6CAAA,CAA+C,CAAA;AAAA,IACxF;AAAA,EACF,CAAA,MAAO;AACL,IAAG,EAAA,CAAA,SAAA,CAAU,UAAA,EAAY,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,EAC9C;AAGA,EAAA,MAAM,gBAAgB,QAAA,KAAa,OAAA,GAAU,iBAAiB,IAAI,CAAA,GAAI,mBAAmB,IAAI,CAAA;AAG7F,EAAA,KAAA,MAAW,CAAC,QAAA,EAAU,OAAO,KAAK,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAA,EAAG;AAC/D,IAAA,MAAM,QAAA,GAAgB,IAAA,CAAA,IAAA,CAAK,UAAA,EAAY,QAAQ,CAAA;AAC/C,IAAA,MAAM,GAAA,GAAW,aAAQ,QAAQ,CAAA;AAGjC,IAAA,IAAI,CAAI,EAAA,CAAA,UAAA,CAAW,GAAG,CAAA,EAAG;AACvB,MAAG,EAAA,CAAA,SAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,IACvC;AAGA,IAAG,EAAA,CAAA,aAAA,CAAc,QAAA,EAAU,OAAA,EAAS,OAAO,CAAA;AAAA,EAC7C;AAGA,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,IAAI;AACF,MAAA,QAAA,CAAS,YAAY,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,UAAU,CAAA;AAAA,IAC3D,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,IAAI;AAEF,MAAA,IAAI;AACF,QAAA,QAAA,CAAS,gBAAgB,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,WAAW,CAAA;AAAA,MAChE,CAAA,CAAA,MAAQ;AACN,QAAA,QAAA,CAAS,eAAe,EAAE,GAAA,EAAK,UAAA,EAAY,KAAA,EAAO,WAAW,CAAA;AAAA,MAC/D;AAAA,IACF,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAA,CAAQ,KAAK,wDAAwD,CAAA;AAAA,IACvE;AAAA,EACF;AACF","file":"index.js","sourcesContent":["/**\n * @mcp-apps-kit/create-app\n *\n * Project scaffolding for MCP applications.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CreateAppOptions {\n name: string;\n template: \"react\" | \"vanilla\";\n directory?: string;\n skipInstall?: boolean;\n skipGit?: boolean;\n}\n\n// =============================================================================\n// Template Content\n// =============================================================================\n\nfunction getReactTemplate(name: string): Record<string, string> {\n return {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: 'concurrently \"pnpm dev:server\" \"pnpm dev:ui\"',\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: \"pnpm build:ui && tsc\",\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": \"^0.1.0\",\n \"@mcp-apps-kit/ui\": \"^0.1.0\",\n \"@mcp-apps-kit/ui-react\": \"^0.1.0\",\n react: \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n zod: \"^3.22.0\",\n },\n devDependencies: {\n \"@types/react\": \"^18.2.0\",\n \"@types/react-dom\": \"^18.2.0\",\n \"@vitejs/plugin-react\": \"^4.2.0\",\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n jsx: \"react-jsx\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/App.tsx\": `/**\n * ${name} - UI Component\n */\n\nimport {\n useAppsClient,\n useHostContext,\n useDocumentTheme,\n useHostStyleVariables,\n} from \"@mcp-apps-kit/ui-react\";\n\nexport function App() {\n const client = useAppsClient();\n const context = useHostContext();\n\n // Apply theme and host styles\n useDocumentTheme(\"light\", \"dark\");\n useHostStyleVariables();\n\n // Get tool output from client\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n\n return (\n <div className=\"container\">\n {output?.message ? (\n <div className=\"greeting\">\n <h1>{output.message}</h1>\n <p className=\"timestamp\">Sent at: {output.timestamp}</p>\n </div>\n ) : (\n <p className=\"waiting\">Waiting for greeting...</p>\n )}\n\n <button\n className=\"button\"\n onClick={() => client.sendFollowUpMessage(\"Please greet me again!\")}\n >\n Request New Greeting\n </button>\n\n <footer className=\"meta\">\n Theme: {context.theme} | Locale: {context.locale}\n </footer>\n </div>\n );\n}\n`,\n \"ui/src/main.tsx\": `/**\n * ${name} - UI Entry Point\n */\n\nimport React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { AppsProvider } from \"@mcp-apps-kit/ui-react\";\nimport { App } from \"./App\";\nimport \"./styles.css\";\n\nconst root = document.getElementById(\"root\");\nif (!root) throw new Error(\"Root element not found\");\n\ncreateRoot(root).render(\n <React.StrictMode>\n <AppsProvider>\n <App />\n </AppsProvider>\n </React.StrictMode>\n);\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [react(), viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"dist\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\npnpm install\npnpm dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\npnpm build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n`,\n };\n}\n\nfunction getVanillaTemplate(name: string): Record<string, string> {\n return {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: 'concurrently \"pnpm dev:server\" \"pnpm dev:ui\"',\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: \"pnpm build:ui && tsc\",\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": \"^0.1.0\",\n \"@mcp-apps-kit/ui\": \"^0.1.0\",\n zod: \"^3.22.0\",\n },\n devDependencies: {\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/main.ts\": `/**\n * ${name} - UI Entry Point\n */\n\nimport { createClient } from \"@mcp-apps-kit/ui\";\nimport \"./styles.css\";\n\nasync function main() {\n const client = await createClient();\n\n // Get container\n const container = document.getElementById(\"app\");\n if (!container) throw new Error(\"Container not found\");\n\n // Render initial UI\n render(container, client);\n\n // Subscribe to context changes\n client.onHostContextChange((context) => {\n document.documentElement.className = context.theme;\n render(container, client);\n });\n}\n\nfunction render(container: HTMLElement, client: ReturnType<typeof createClient> extends Promise<infer T> ? T : never) {\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n const context = client.hostContext;\n\n container.innerHTML = \\`\n <div class=\"container\">\n \\${output?.message ? \\`\n <div class=\"greeting\">\n <h1>\\${output.message}</h1>\n <p class=\"timestamp\">Sent at: \\${output.timestamp}</p>\n </div>\n \\` : \\`\n <p class=\"waiting\">Waiting for greeting...</p>\n \\`}\n\n <button class=\"button\" id=\"request-btn\">\n Request New Greeting\n </button>\n\n <footer class=\"meta\">\n Theme: \\${context.theme} | Locale: \\${context.locale}\n </footer>\n </div>\n \\`;\n\n // Add event listener\n const btn = document.getElementById(\"request-btn\");\n btn?.addEventListener(\"click\", () => {\n client.sendFollowUpMessage(\"Please greet me again!\");\n });\n}\n\nmain();\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.ts\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"dist\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\npnpm install\npnpm dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\npnpm build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n`,\n };\n}\n\n// =============================================================================\n// Scaffolding Logic\n// =============================================================================\n\n/**\n * Scaffold a new MCP application project\n */\nexport async function scaffoldProject(options: CreateAppOptions): Promise<void> {\n const { name, template, directory, skipInstall = false, skipGit = false } = options;\n\n // Determine project directory\n const projectDir = directory ?? path.resolve(process.cwd(), name);\n\n // Check if directory exists and is not empty\n if (fs.existsSync(projectDir)) {\n const files = fs.readdirSync(projectDir);\n if (files.length > 0) {\n throw new Error(`Directory ${projectDir} is not empty. Please use an empty directory.`);\n }\n } else {\n fs.mkdirSync(projectDir, { recursive: true });\n }\n\n // Get template files\n const templateFiles = template === \"react\" ? getReactTemplate(name) : getVanillaTemplate(name);\n\n // Write all files\n for (const [filePath, content] of Object.entries(templateFiles)) {\n const fullPath = path.join(projectDir, filePath);\n const dir = path.dirname(fullPath);\n\n // Create directory if needed\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n fs.writeFileSync(fullPath, content, \"utf-8\");\n }\n\n // Initialize git repository\n if (!skipGit) {\n try {\n execSync(\"git init\", { cwd: projectDir, stdio: \"ignore\" });\n } catch {\n // Ignore git init errors (git may not be installed)\n }\n }\n\n // Install dependencies\n if (!skipInstall) {\n try {\n // Try pnpm first, fall back to npm\n try {\n execSync(\"pnpm install\", { cwd: projectDir, stdio: \"inherit\" });\n } catch {\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n }\n } catch {\n // eslint-disable-next-line no-console\n console.warn(\"Warning: Could not install dependencies automatically.\");\n }\n }\n}\n"]}
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @mcp-apps-kit/create-app\n *\n * Project scaffolding for MCP applications.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface CreateAppOptions {\n name: string;\n template: \"react\" | \"vanilla\";\n directory?: string;\n vercel?: boolean;\n skipInstall?: boolean;\n skipGit?: boolean;\n}\n\n// =============================================================================\n// Version Detection\n// =============================================================================\n\ninterface PackageVersions {\n core: string;\n ui: string;\n uiReact: string;\n}\n\n// Cache for fetched versions\nlet cachedVersions: PackageVersions | null = null;\n\n/**\n * Fetch the latest version of a package from npm registry\n */\nfunction fetchLatestVersion(packageName: string): string {\n try {\n const result = execSync(`npm view ${packageName} version`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n return `^${result}`;\n } catch {\n // Fallback to a reasonable default if we can't fetch\n return \"^0.2.0\";\n }\n}\n\n/**\n * Get the versions of @mcp-apps-kit packages from npm registry\n */\nfunction getPackageVersions(): PackageVersions {\n if (cachedVersions) {\n return cachedVersions;\n }\n\n cachedVersions = {\n core: fetchLatestVersion(\"@mcp-apps-kit/core\"),\n ui: fetchLatestVersion(\"@mcp-apps-kit/ui\"),\n uiReact: fetchLatestVersion(\"@mcp-apps-kit/ui-react\"),\n };\n\n return cachedVersions;\n}\n\n// =============================================================================\n// Template Content\n// =============================================================================\n\nfunction getReactTemplate(name: string, vercel = false): Record<string, string> {\n const uiOutputDir = vercel ? \"public\" : \"dist\";\n const packageManager = vercel ? \"npm\" : \"pnpm\";\n const versions = getPackageVersions();\n\n const files: Record<string, string> = {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: `concurrently \"${packageManager} run dev:server\" \"${packageManager} run dev:ui\"`,\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: `${packageManager} run build:ui && tsc`,\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": versions.core,\n \"@mcp-apps-kit/ui\": versions.ui,\n \"@mcp-apps-kit/ui-react\": versions.uiReact,\n react: \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n zod: \"^3.22.0\",\n ...(vercel ? { express: \"^4.21.0\" } : {}),\n },\n devDependencies: {\n \"@types/react\": \"^18.2.0\",\n \"@types/react-dom\": \"^18.2.0\",\n \"@vitejs/plugin-react\": \"^4.2.0\",\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n jsx: \"react-jsx\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": vercel\n ? `/**\n * ${name} - MCP Server\n */\n\n// Required for Vercel to detect Express\nimport \"express\";\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./${uiOutputDir}/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Only start locally - Vercel uses the exported Express app\nif (!process.env.VERCEL) {\n await app.start({ port: 3000 });\n console.log(\"MCP server running on http://localhost:3000\");\n}\n\n// Export Express app for Vercel\nexport default app.expressApp;\n`\n : `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/App.tsx\": `/**\n * ${name} - UI Component\n */\n\nimport {\n useAppsClient,\n useHostContext,\n useDocumentTheme,\n useHostStyleVariables,\n} from \"@mcp-apps-kit/ui-react\";\n\nexport function App() {\n const client = useAppsClient();\n const context = useHostContext();\n\n // Apply theme and host styles\n useDocumentTheme(\"light\", \"dark\");\n useHostStyleVariables();\n\n // Get tool output from client\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n\n return (\n <div className=\"container\">\n {output?.message ? (\n <div className=\"greeting\">\n <h1>{output.message}</h1>\n <p className=\"timestamp\">Sent at: {output.timestamp}</p>\n </div>\n ) : (\n <p className=\"waiting\">Waiting for greeting...</p>\n )}\n\n <button\n className=\"button\"\n onClick={() => client.sendFollowUpMessage(\"Please greet me again!\")}\n >\n Request New Greeting\n </button>\n\n <footer className=\"meta\">\n Theme: {context.theme} | Locale: {context.locale}\n </footer>\n </div>\n );\n}\n`,\n \"ui/src/main.tsx\": `/**\n * ${name} - UI Entry Point\n */\n\nimport React from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { AppsProvider } from \"@mcp-apps-kit/ui-react\";\nimport { App } from \"./App\";\nimport \"./styles.css\";\n\nconst root = document.getElementById(\"root\");\nif (!root) throw new Error(\"Root element not found\");\n\ncreateRoot(root).render(\n <React.StrictMode>\n <AppsProvider>\n <App />\n </AppsProvider>\n </React.StrictMode>\n);\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/src/main.tsx\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [react(), viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"${uiOutputDir}\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\npublic/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\n${packageManager} install\n${packageManager} run dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\n${packageManager} run build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n${\n vercel\n ? `\n## Deploy to Vercel\n\nThis project is configured for Vercel deployment:\n\n\\`\\`\\`bash\nvercel deploy\n\\`\\`\\`\n\nThen use the deployed URL as your MCP server endpoint.\n`\n : \"\"\n}\n`,\n };\n\n // Add vercel.json if Vercel setup is enabled\n if (vercel) {\n files[\"vercel.json\"] = JSON.stringify(\n {\n installCommand: \"npm install\",\n buildCommand: \"npm run build:ui\",\n outputDirectory: \".\",\n functions: {\n \"server/index.ts\": {\n includeFiles: `${uiOutputDir}/**`,\n },\n },\n rewrites: [\n {\n source: \"/(.*)\",\n destination: \"/server/index.ts\",\n },\n ],\n },\n null,\n 2\n );\n }\n\n return files;\n}\n\nfunction getVanillaTemplate(name: string, vercel = false): Record<string, string> {\n const uiOutputDir = vercel ? \"public\" : \"dist\";\n const packageManager = vercel ? \"npm\" : \"pnpm\";\n const versions = getPackageVersions();\n\n const files: Record<string, string> = {\n \"package.json\": JSON.stringify(\n {\n name,\n version: \"0.1.0\",\n type: \"module\",\n scripts: {\n dev: `concurrently \"${packageManager} run dev:server\" \"${packageManager} run dev:ui\"`,\n \"dev:server\": \"tsx watch server/index.ts\",\n \"dev:ui\": \"vite --config ui/vite.config.ts\",\n build: `${packageManager} run build:ui && tsc`,\n \"build:ui\": \"vite build --config ui/vite.config.ts\",\n start: \"node dist/server/index.js\",\n },\n dependencies: {\n \"@mcp-apps-kit/core\": versions.core,\n \"@mcp-apps-kit/ui\": versions.ui,\n zod: \"^3.22.0\",\n ...(vercel ? { express: \"^4.21.0\" } : {}),\n },\n devDependencies: {\n concurrently: \"^8.2.0\",\n tsx: \"^4.7.0\",\n typescript: \"^5.3.0\",\n vite: \"^5.0.0\",\n \"vite-plugin-singlefile\": \"^2.0.0\",\n },\n },\n null,\n 2\n ),\n \"tsconfig.json\": JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2020\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: true,\n outDir: \"dist\",\n },\n include: [\"server/**/*\", \"ui/src/**/*\"],\n exclude: [\"node_modules\", \"dist\"],\n },\n null,\n 2\n ),\n \"server/index.ts\": vercel\n ? `/**\n * ${name} - MCP Server\n */\n\n// Required for Vercel to detect Express\nimport \"express\";\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./${uiOutputDir}/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Only start locally - Vercel uses the exported Express app\nif (!process.env.VERCEL) {\n await app.start({ port: 3000 });\n console.log(\"MCP server running on http://localhost:3000\");\n}\n\n// Export Express app for Vercel\nexport default app.expressApp;\n`\n : `/**\n * ${name} - MCP Server\n */\n\nimport { createApp } from \"@mcp-apps-kit/core\";\nimport { z } from \"zod\";\n\nconst app = createApp({\n name: \"${name}\",\n version: \"0.1.0\",\n\n tools: {\n hello: {\n description: \"Say hello to someone\",\n input: z.object({\n name: z.string().describe(\"Name to greet\"),\n }),\n output: z.object({\n message: z.string(),\n timestamp: z.string(),\n }),\n handler: async ({ name }) => {\n return {\n message: \\`Hello, \\${name}!\\`,\n timestamp: new Date().toISOString(),\n };\n },\n ui: \"greeting\",\n },\n },\n\n ui: {\n greeting: {\n html: \"./ui/dist/index.html\",\n description: \"Greeting widget\",\n prefersBorder: true,\n },\n },\n});\n\n// Start server\nawait app.start({ port: 3000 });\nconsole.log(\"MCP server running on http://localhost:3000\");\n`,\n \"ui/src/main.ts\": `/**\n * ${name} - UI Entry Point\n */\n\nimport { createClient } from \"@mcp-apps-kit/ui\";\nimport \"./styles.css\";\n\nasync function main() {\n const client = await createClient();\n\n // Get container\n const container = document.getElementById(\"app\");\n if (!container) throw new Error(\"Container not found\");\n\n // Render initial UI\n render(container, client);\n\n // Subscribe to context changes\n client.onHostContextChange((context) => {\n document.documentElement.className = context.theme;\n render(container, client);\n });\n}\n\nfunction render(container: HTMLElement, client: ReturnType<typeof createClient> extends Promise<infer T> ? T : never) {\n const output = client.toolOutput as { message?: string; timestamp?: string } | undefined;\n const context = client.hostContext;\n\n container.innerHTML = \\`\n <div class=\"container\">\n \\${output?.message ? \\`\n <div class=\"greeting\">\n <h1>\\${output.message}</h1>\n <p class=\"timestamp\">Sent at: \\${output.timestamp}</p>\n </div>\n \\` : \\`\n <p class=\"waiting\">Waiting for greeting...</p>\n \\`}\n\n <button class=\"button\" id=\"request-btn\">\n Request New Greeting\n </button>\n\n <footer class=\"meta\">\n Theme: \\${context.theme} | Locale: \\${context.locale}\n </footer>\n </div>\n \\`;\n\n // Add event listener\n const btn = document.getElementById(\"request-btn\");\n btn?.addEventListener(\"click\", () => {\n client.sendFollowUpMessage(\"Please greet me again!\");\n });\n}\n\nmain();\n`,\n \"ui/src/styles.css\": `* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n padding: 16px;\n}\n\n.container {\n max-width: 400px;\n margin: 0 auto;\n}\n\n.greeting h1 {\n font-size: 1.5rem;\n margin-bottom: 8px;\n}\n\n.timestamp {\n color: #666;\n font-size: 0.875rem;\n}\n\n.waiting {\n color: #999;\n font-style: italic;\n}\n\n.button {\n margin-top: 16px;\n padding: 8px 16px;\n background: #0066cc;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.button:hover {\n background: #0052a3;\n}\n\n.meta {\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #eee;\n font-size: 0.75rem;\n color: #999;\n}\n\n/* Dark mode support */\n.dark body {\n background: #1a1a1a;\n color: #fff;\n}\n\n.dark .timestamp {\n color: #aaa;\n}\n\n.dark .meta {\n border-color: #333;\n color: #666;\n}\n`,\n \"ui/index.html\": `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${name}</title>\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.ts\"></script>\n </body>\n</html>\n`,\n \"ui/vite.config.ts\": `import { defineConfig } from \"vite\";\nimport { viteSingleFile } from \"vite-plugin-singlefile\";\n\nexport default defineConfig({\n plugins: [viteSingleFile()],\n root: \"./ui\",\n build: {\n outDir: \"${uiOutputDir}\",\n emptyOutDir: true,\n },\n});\n`,\n \".gitignore\": `node_modules/\ndist/\npublic/\n*.log\n.env\n.env.local\n`,\n \"README.md\": `# ${name}\n\nAn MCP application built with @mcp-apps-kit.\n\n## Development\n\n\\`\\`\\`bash\n${packageManager} install\n${packageManager} run dev\n\\`\\`\\`\n\n## Build\n\n\\`\\`\\`bash\n${packageManager} run build\n\\`\\`\\`\n\n## Connecting to Claude Desktop\n\nAdd to your Claude Desktop config:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"${name}\": {\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"path/to/${name}/server/index.ts\"]\n }\n }\n}\n\\`\\`\\`\n${\n vercel\n ? `\n## Deploy to Vercel\n\nThis project is configured for Vercel deployment:\n\n\\`\\`\\`bash\nvercel deploy\n\\`\\`\\`\n\nThen use the deployed URL as your MCP server endpoint.\n`\n : \"\"\n}\n`,\n };\n\n // Add vercel.json if Vercel setup is enabled\n if (vercel) {\n files[\"vercel.json\"] = JSON.stringify(\n {\n installCommand: \"npm install\",\n buildCommand: \"npm run build:ui\",\n outputDirectory: \".\",\n functions: {\n \"server/index.ts\": {\n includeFiles: `${uiOutputDir}/**`,\n },\n },\n rewrites: [\n {\n source: \"/(.*)\",\n destination: \"/server/index.ts\",\n },\n ],\n },\n null,\n 2\n );\n }\n\n return files;\n}\n\n// =============================================================================\n// Scaffolding Logic\n// =============================================================================\n\n/**\n * Scaffold a new MCP application project\n */\nexport async function scaffoldProject(options: CreateAppOptions): Promise<void> {\n const {\n name,\n template,\n directory,\n vercel = false,\n skipInstall = false,\n skipGit = false,\n } = options;\n\n // Determine project directory\n const projectDir = directory ?? path.resolve(process.cwd(), name);\n\n // Check if directory exists and is not empty\n if (fs.existsSync(projectDir)) {\n const files = fs.readdirSync(projectDir);\n if (files.length > 0) {\n throw new Error(`Directory ${projectDir} is not empty. Please use an empty directory.`);\n }\n } else {\n fs.mkdirSync(projectDir, { recursive: true });\n }\n\n // Get template files\n const templateFiles =\n template === \"react\" ? getReactTemplate(name, vercel) : getVanillaTemplate(name, vercel);\n\n // Write all files\n for (const [filePath, content] of Object.entries(templateFiles)) {\n const fullPath = path.join(projectDir, filePath);\n const dir = path.dirname(fullPath);\n\n // Create directory if needed\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Write file\n fs.writeFileSync(fullPath, content, \"utf-8\");\n }\n\n // Initialize git repository\n if (!skipGit) {\n try {\n execSync(\"git init\", { cwd: projectDir, stdio: \"ignore\" });\n } catch {\n // Ignore git init errors (git may not be installed)\n }\n }\n\n // Install dependencies\n if (!skipInstall) {\n try {\n if (vercel) {\n // Use npm for Vercel projects (better compatibility)\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n } else {\n // Try pnpm first, fall back to npm\n try {\n execSync(\"pnpm install\", { cwd: projectDir, stdio: \"inherit\" });\n } catch {\n execSync(\"npm install\", { cwd: projectDir, stdio: \"inherit\" });\n }\n }\n } catch {\n // eslint-disable-next-line no-console\n console.warn(\"Warning: Could not install dependencies automatically.\");\n }\n }\n}\n"]}
{
"name": "@mcp-apps-kit/create-app",
"version": "0.2.2",
"version": "0.2.3",
"description": "CLI tool for scaffolding MCP applications",

@@ -5,0 +5,0 @@ "type": "module",

@@ -59,3 +59,3 @@ # @mcp-apps-kit/create-app

- ../../examples/minimal
- ../../examples/kanban
- [kanban-mcp-example](https://github.com/AndurilCode/kanban-mcp-example) (comprehensive demo in separate repo)

@@ -62,0 +62,0 @@ ## License