Skip to main content
Glama
masamunet

npm-dev-mcp

by masamunet

start_dev_server

Start npm development server in background for specified directory. Automatically detects projects and manages processes.

Instructions

指定ディレクトリでnpm run devをバックグラウンドで開始

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
directoryNo実行ディレクトリ(オプション、未指定時は自動検出)

Implementation Reference

  • Main tool handler: orchestrates project scanning, env loading, ProcessManager invocation, and formats response with process details and ports.
    export async function startDevServer(args: { directory?: string }): Promise<string> {
      try {
        logger.info('Starting dev server', { directory: args.directory });
    
        let targetDirectory = args.directory;
        let envPath: string | undefined;
    
        // If no directory specified, auto-detect
        if (!targetDirectory) {
          const scanner = new ProjectScanner();
          const bestProject = await scanner.findBestProject();
    
          if (!bestProject) {
            return JSON.stringify({
              success: false,
              message: 'devスクリプトが定義されたpackage.jsonが見つかりませんでした。scan_project_dirsを実行して利用可能なプロジェクトを確認してください。'
            });
          }
    
          targetDirectory = bestProject.directory;
          envPath = bestProject.envPath;
          logger.info(`Auto-detected project directory: ${targetDirectory}`);
        }
    
        // Load environment variables
        const envLoader = new EnvLoader();
        const env = await envLoader.prepareEnvironment(envPath);
    
        // Start the dev server
        const processManager = ProcessManager.getInstance();
        const devProcess = await processManager.startDevServer(targetDirectory, env);
    
        // Wait a moment to get initial status
        await new Promise(resolve => setTimeout(resolve, 2000));
        // Wait a moment to get initial status
        await new Promise(resolve => setTimeout(resolve, 2000));
        await processManager.getStatus(); // Update status/ports as side effect
    
        const result = {
          success: true,
          message: 'Dev serverが開始されました',
          process: {
            pid: devProcess.pid,
            directory: devProcess.directory,
            status: devProcess.status,
            startTime: devProcess.startTime,
            ports: devProcess.ports
          },
          environment: {
            hasEnvFile: !!envPath,
            envPath,
            nodeEnv: env.NODE_ENV || 'development'
          }
        };
    
        if (devProcess.ports.length > 0) {
          result.message += `\n起動ポート: ${devProcess.ports.join(', ')}`;
        }
    
        logger.info(`Dev server started successfully`, {
          pid: devProcess.pid,
          ports: devProcess.ports
        });
    
        return JSON.stringify(result, null, 2);
    
      } catch (error) {
        logger.error('Failed to start dev server', { error });
        return JSON.stringify({
          success: false,
          message: `Dev serverの開始に失敗しました: ${error}`,
          error: String(error)
        });
      }
    }
  • Tool schema defining name, description, and optional directory input.
    export const startDevServerSchema: Tool = {
      name: 'start_dev_server',
      description: '指定ディレクトリでnpm run devをバックグラウンドで開始',
      inputSchema: {
        type: 'object',
        properties: {
          directory: {
            type: 'string',
            description: '実行ディレクトリ(オプション、未指定時は自動検出)'
          }
        },
        additionalProperties: false
      }
    };
  • src/index.ts:137-145 (registration)
    Tool dispatch in CallToolRequestSchema handler: calls startDevServer and returns text content.
    case 'start_dev_server':
      return {
        content: [
          {
            type: 'text',
            text: await startDevServer(args as { directory?: string }),
          },
        ],
      };
  • src/index.ts:55-65 (registration)
    Registration of tool schema in the ListToolsRequestSchema response array.
    const tools = [
      scanProjectDirsSchema,
      startDevServerSchema,
      getDevStatusSchema,
      getDevLogsSchema,
      stopDevServerSchema,
      restartDevServerSchema,
      getHealthStatusSchema,
      recoverFromStateSchema,
      autoRecoverSchema,
    ];
  • Core helper function in ProcessManager that spawns 'npm run dev', manages process lifecycle, logging, port detection, and state persistence.
    async startDevServer(
      directory?: string,
      env?: Record<string, string>
    ): Promise<DevProcess> {
      // Use project context if no directory specified
      let targetDirectory = directory;
      if (!targetDirectory) {
        const contextManager = ProjectContextManager.getInstance();
        if (contextManager.isInitialized()) {
          targetDirectory = contextManager.getContext().rootDirectory;
        } else {
          targetDirectory = process.cwd();
        }
      }
    
      this.logger.info(`Starting dev server in ${targetDirectory}`);
    
      // Check if a process is already running for this directory
      const existingProcess = this.processes.get(targetDirectory);
      if (existingProcess && await this.isProcessRunning(existingProcess)) {
        this.logger.info(`Dev server is already running for ${targetDirectory}`);
        return existingProcess.info;
      }
    
      try {
        // Clean up any stale process for this directory
        if (existingProcess) {
          await this.cleanupProcess(targetDirectory);
        }
    
        // Spawn the npm run dev process
        const childProcess = spawn('npm', ['run', 'dev'], {
          cwd: targetDirectory,
          env: env || process.env,
          detached: false, // Keep attached for better control
          stdio: ['ignore', 'pipe', 'pipe']
        });
    
        const pid = childProcess.pid!;
    
        // Create properties
        const logManager = new LogManager();
    
        const processInfo: DevProcess = {
          pid,
          directory: targetDirectory,
          status: 'starting',
          startTime: new Date(),
          ports: []
        };
    
        // Store in map
        this.processes.set(targetDirectory, {
          info: processInfo,
          child: childProcess,
          logManager
        });
    
        // Start logging
        await logManager.startLogging(childProcess);
    
        // Set up process event handlers
        this.setupProcessHandlers(targetDirectory, childProcess);
    
        // Wait a moment for the process to potentially start
        await this.waitForProcessStart(targetDirectory);
    
        // Detect ports after a short delay
        setTimeout(async () => {
          const proc = this.processes.get(targetDirectory);
          if (proc) {
            proc.info.ports = await this.portDetector.getPortsByPid(pid);
            this.logger.info(`Detected ports for ${targetDirectory}: ${proc.info.ports.join(', ')}`);
            this.saveCurrentState();
          }
        }, 3000);
    
        this.logger.info(`Dev server started with PID ${pid} for ${targetDirectory}`);
        return processInfo;
    
      } catch (error) {
        this.logger.error(`Failed to start dev server for ${targetDirectory}`, { error });
        const proc = this.processes.get(targetDirectory);
        if (proc) {
          proc.info.status = 'error';
        }
        throw new Error(`Failed to start dev server: ${error}`);
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions running 'npm run dev' in the background, which implies a long-running process, but doesn't describe what happens if a server is already running, error handling, or output behavior. The description adds minimal context beyond the basic action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence in Japanese that directly states the tool's function. It's front-loaded with the core action and includes key details like 'バックグラウンドで' (in the background). There's no wasted text, making it appropriately concise for its purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (starting a background process) and lack of annotations and output schema, the description is incomplete. It doesn't explain what 'npm run dev' entails, how to verify success, or potential side effects. For a tool that initiates a server process, more context on behavior and outcomes is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, with one optional parameter 'directory' documented as '実行ディレクトリ(オプション、未指定時は自動検出)'. The description doesn't add any parameter details beyond what the schema provides, such as format examples or constraints. With high schema coverage, the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'npm run devをバックグラウンドで開始' (start npm run dev in the background). It specifies the action (start) and resource (npm run dev), though it doesn't explicitly differentiate from sibling tools like 'restart_dev_server' or 'stop_dev_server'. The description is specific but lacks sibling distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention when to choose 'start_dev_server' over 'restart_dev_server' or other siblings, nor does it indicate any prerequisites or exclusions. Usage is implied from the action, but no explicit guidelines are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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/masamunet/npm-dev-mcp'

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