diff --git a/package-lock.json b/package-lock.json index 1d152f8..1978722 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@agentailor/create-mcp-server", - "version": "0.5.3", + "version": "0.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@agentailor/create-mcp-server", - "version": "0.5.3", + "version": "0.6.1", "license": "MIT", "dependencies": { "commander": "^14.0.3", diff --git a/package.json b/package.json index aee6828..4addc7e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@agentailor/create-mcp-server", - "version": "0.6.0", + "version": "0.6.1", "description": "Create a new MCP (Model Context Protocol) server project", "type": "module", "bin": { @@ -17,7 +17,9 @@ "lint:fix": "eslint src/ --fix", "format": "prettier --write src/", "format:check": "prettier --check src/", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "update-template-deps": "node scripts/update-template-deps.mjs", + "update-template-deps:dry": "node scripts/update-template-deps.mjs --dry-run" }, "keywords": [ "mcp", diff --git a/scripts/update-template-deps.mjs b/scripts/update-template-deps.mjs new file mode 100644 index 0000000..7093cb0 --- /dev/null +++ b/scripts/update-template-deps.mjs @@ -0,0 +1,116 @@ +#!/usr/bin/env node +/** + * Fetches the latest versions of all template dependencies from npm and + * updates the hardcoded version strings in src/templates/common/package.json.ts. + * + * Usage via npm scripts: + * npm run update-template-deps # update in place + * npm run update-template-deps:dry # print changes only, no + * Usage via direct node command: + * node scripts/update-template-deps.mjs # update in place + * node scripts/update-template-deps.mjs --dry-run # print changes only + */ + +import { execSync } from 'child_process'; +import { readFileSync, writeFileSync } from 'fs'; +import { resolve, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const TEMPLATE_FILE = resolve(__dirname, '../src/templates/common/package.json.ts'); +const DRY_RUN = process.argv.includes('--dry-run'); + +const TEMPLATE_PACKAGES = [ + '@modelcontextprotocol/sdk', + '@modelcontextprotocol/inspector', + 'express', + 'fastmcp', + 'zod', + 'dotenv', + 'jose', + 'typescript', + '@types/node', + '@types/express', +]; + +function getLatestVersion(pkg) { + try { + return execSync(`npm view ${pkg} version`, { encoding: 'utf8' }).trim(); + } catch (err) { + console.error(` Failed to fetch version for ${pkg}: ${err.message}`); + return null; + } +} + +// Escapes special regex characters in a package name (e.g. @, /) +function escapeRegex(str) { + return str.replace(/[.*+?^${}()|[\]\\@/]/g, '\\$&'); +} + +function updateVersionInContent(content, pkg, newVersion) { + // Pattern 1: quoted key — '@scope/pkg': '^1.0.0' or "@scope/pkg": "^1.0.0" + const quotedKey = new RegExp( + `(['"]${escapeRegex(pkg)}['"]\\s*:\\s*['"])\\^[\\d.]+(['"])`, + 'g' + ); + // Pattern 2: unquoted key — pkg: '^1.0.0' + const unquotedKey = new RegExp( + `(\\b${escapeRegex(pkg)}\\s*:\\s*['"])\\^[\\d.]+(['"])`, + 'g' + ); + // Pattern 3: bracket assignment — dependencies['pkg'] = '^1.0.0' + const bracketAssign = new RegExp( + `(\\[['"]${escapeRegex(pkg)}['"]\\]\\s*=\\s*['"])\\^[\\d.]+(['"])`, + 'g' + ); + return content + .replace(quotedKey, `$1^${newVersion}$2`) + .replace(unquotedKey, `$1^${newVersion}$2`) + .replace(bracketAssign, `$1^${newVersion}$2`); +} + +async function main() { + console.log(`Fetching latest versions for ${TEMPLATE_PACKAGES.length} packages...\n`); + + let content = readFileSync(TEMPLATE_FILE, 'utf8'); + let hasChanges = false; + + for (const pkg of TEMPLATE_PACKAGES) { + const newVersion = getLatestVersion(pkg); + if (!newVersion) continue; + + // Extract current file version BEFORE comparison or mutation. + // Tries quoted key, unquoted key, and bracket assignment forms. + const oldMatch = + content.match(new RegExp(`['"]${escapeRegex(pkg)}['"]\\s*:\\s*['"]\\^([\\d.]+)['"]`)) || + content.match(new RegExp(`\\b${escapeRegex(pkg)}\\s*:\\s*['"]\\^([\\d.]+)['"]`)) || + content.match(new RegExp(`\\[['"]${escapeRegex(pkg)}['"]\\]\\s*=\\s*['"]\\^([\\d.]+)['"]`)); + const oldVersion = oldMatch ? oldMatch[1] : '?'; + + const updated = updateVersionInContent(content, pkg, newVersion); + + if (updated === content) { + console.log(` ${pkg}: ^${oldVersion} (up to date)`); + } else { + console.log(` ${pkg}: ^${oldVersion} → ^${newVersion}`); + content = updated; + hasChanges = true; + } + } + + console.log(); + + if (!hasChanges) { + console.log('All packages are already at their latest versions. Nothing to update.'); + return; + } + + if (DRY_RUN) { + console.log('Dry run — no files were written.'); + } else { + writeFileSync(TEMPLATE_FILE, content, 'utf8'); + console.log(`Updated: src/templates/common/package.json.ts`); + } +} + +main(); diff --git a/src/templates/common/package.json.ts b/src/templates/common/package.json.ts index 873df40..acbfc1c 100644 --- a/src/templates/common/package.json.ts +++ b/src/templates/common/package.json.ts @@ -12,17 +12,17 @@ export function getPackageJsonTemplate( let devDependencies: Record; const commonDevDependencies = { - typescript: '^5.9.3', - '@modelcontextprotocol/inspector': '^0.20.0', - '@types/node': '^25.3.0', + typescript: '^6.0.2', + '@modelcontextprotocol/inspector': '^0.21.1', + '@types/node': '^25.5.2', }; const zodDependency = { zod: '^4.3.6' }; - const dotEnvDependency = { dotenv: '^17.3.1' }; + const dotEnvDependency = { dotenv: '^17.4.1' }; if (framework === 'fastmcp') { // FastMCP dependencies - simpler setup dependencies = { - fastmcp: '^3.33.0', + fastmcp: '^3.35.0', ...zodDependency, ...dotEnvDependency, }; @@ -33,7 +33,7 @@ export function getPackageJsonTemplate( } else if (transport === 'stdio') { // Official SDK stdio - no express needed dependencies = { - '@modelcontextprotocol/sdk': '^1.26.0', + '@modelcontextprotocol/sdk': '^1.29.0', ...zodDependency, ...dotEnvDependency, }; @@ -44,14 +44,14 @@ export function getPackageJsonTemplate( } else { // Official SDK HTTP dependencies dependencies = { - '@modelcontextprotocol/sdk': '^1.26.0', + '@modelcontextprotocol/sdk': '^1.29.0', express: '^5.2.1', ...zodDependency, ...dotEnvDependency, }; if (withOAuth) { - dependencies['jose'] = '^6.1.3'; + dependencies['jose'] = '^6.2.2'; } devDependencies = { diff --git a/src/templates/common/tsconfig.json.ts b/src/templates/common/tsconfig.json.ts index ff71fc3..a948d2d 100644 --- a/src/templates/common/tsconfig.json.ts +++ b/src/templates/common/tsconfig.json.ts @@ -11,6 +11,7 @@ export function getTsconfigTemplate(): string { skipLibCheck: true, forceConsistentCasingInFileNames: true, declaration: true, + types: ['node'], }, include: ['src/**/*'], exclude: ['node_modules', 'dist'],