Skip to main content
Glama
fstubner
by fstubner

build

Execute the npm build script to compile and prepare your project for deployment using the npm-run-mcp-server.

Instructions

Run npm script "build": node scripts/build.cjs

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
_No
argsNoOptional arguments appended after -- to the script

Implementation Reference

  • Generic handler for all npm script tools including 'build'. Parses tool input to extra arguments, constructs the run command using the detected package manager, executes the process, formats output with status, trims if too long, and returns as text content.
    async (input: Record<string, unknown>) => { const extraArgs = toolInputToExtraArgs(input); const { command, args: runArgs } = buildRunCommand(pm, scriptName, extraArgs); try { const { stdout, stderr, exitCode, signal, totalLength } = await runProcess(command, runArgs, { cwd: projectDir, env: process.env, }); const combined = stdout && stderr ? `${stdout}\n${stderr}` : stdout || stderr || ''; const succeeded = exitCode === 0; const failurePrefix = succeeded ? '' : `Command failed (exit=${exitCode}${signal ? `, signal=${signal}` : ''}): ${command} ${runArgs.join(' ')}`; const combinedWithStatus = failurePrefix ? [failurePrefix, combined].filter(Boolean).join('\n') : combined; const totalLengthWithStatus = failurePrefix ? totalLength + failurePrefix.length + (combined ? 1 : 0) : totalLength; const { text } = trimOutput(combinedWithStatus, 12000, totalLengthWithStatus); return { content: [ { type: 'text', text, }, ], }; } catch (error: any) { const message = error?.message ? String(error.message) : 'Script failed'; const { text } = trimOutput(message); return { content: [ { type: 'text', text, }, ], }; } }
  • Constructs the input schema for script tools. Base schema supports positional args (_) and args string/array. Merges with custom JSON schema from config if provided, converting to Zod.
    function buildToolInputSchema(configForScript: McpScriptConfig | undefined): z.ZodTypeAny { const base = z .object({ _: z.array(z.string()).optional(), args: z .union([z.string(), z.array(z.string())]) .optional() .describe(configForScript?.argsDescription ?? 'Optional arguments appended after -- to the script'), }) .passthrough(); if (!configForScript?.inputSchema) return base; const converted = jsonSchemaToZod(configForScript.inputSchema); if (converted instanceof z.ZodObject) { const merged = converted.extend({ _: base.shape._, args: base.shape.args, }); return configForScript.inputSchema && isPlainObject(configForScript.inputSchema) && configForScript.inputSchema.additionalProperties === false ? merged.strict() : merged.passthrough(); } return base; }
  • src/index.ts:627-680 (registration)
    Loop that registers an MCP tool for each filtered package.json script. Tool name is normalized from scriptName or config.toolName (e.g. 'build'). Registers with description and schema, using the generic handler.
    for (const scriptName of filteredScriptNames) { // Sanitize tool name - MCP tools can only contain [a-z0-9_-] const configForScript = mcpConfig.scripts?.[scriptName]; const toolName = normalizeToolName(configForScript?.toolName ?? scriptName); // Create a more descriptive description const scriptCommand = scripts[scriptName]; const description = configForScript?.description ?? `Run npm script "${scriptName}": ${scriptCommand}`; server.registerTool( toolName, { description, inputSchema: buildToolInputSchema(configForScript), }, async (input: Record<string, unknown>) => { const extraArgs = toolInputToExtraArgs(input); const { command, args: runArgs } = buildRunCommand(pm, scriptName, extraArgs); try { const { stdout, stderr, exitCode, signal, totalLength } = await runProcess(command, runArgs, { cwd: projectDir, env: process.env, }); const combined = stdout && stderr ? `${stdout}\n${stderr}` : stdout || stderr || ''; const succeeded = exitCode === 0; const failurePrefix = succeeded ? '' : `Command failed (exit=${exitCode}${signal ? `, signal=${signal}` : ''}): ${command} ${runArgs.join(' ')}`; const combinedWithStatus = failurePrefix ? [failurePrefix, combined].filter(Boolean).join('\n') : combined; const totalLengthWithStatus = failurePrefix ? totalLength + failurePrefix.length + (combined ? 1 : 0) : totalLength; const { text } = trimOutput(combinedWithStatus, 12000, totalLengthWithStatus); return { content: [ { type: 'text', text, }, ], }; } catch (error: any) { const message = error?.message ? String(error.message) : 'Script failed'; const { text } = trimOutput(message); return { content: [ { type: 'text', text, }, ], }; } } ); }
  • Normalizes potential tool names to valid MCP tool name format: lowercase letters, digits, underscores, hyphens.
    function normalizeToolName(name: string): string { const normalized = name.toLowerCase().replace(/[^a-z0-9_-]/g, '_'); return normalized.length > 0 ? normalized : 'script'; }
  • Builds the command and arguments array for running the npm script with package manager (e.g. 'npm run build -- args').
    function buildRunCommand( pm: PackageManager, scriptName: string, extraArgs: string[] ): { command: string; args: string[] } { const command = pm; const baseArgs = ['run', scriptName]; const args = extraArgs.length > 0 ? [...baseArgs, '--', ...extraArgs] : baseArgs; return { command, args }; }
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/fstubner/npm-run-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server