get_running_services
Checks common development ports to list running processes and identify expected services that are missing.
Instructions
Lists processes running on common dev ports (3000, 4000, 5173, 8080 etc). Shows what is running and what is expected but missing.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cwd | No |
Implementation Reference
- src/tools/processes.ts:14-59 (handler)Main handler function `getRunningServices` that checks expected ports using find-process and returns running services and missing ports.
export async function getRunningServices( expectedPorts: number[] ): Promise<ProcessResult> { const checks = await Promise.allSettled( expectedPorts.map(async (port) => { try { const results = await findProcess("port", port); if (results.length > 0) { const first = results[0]; return { running: { port, pid: first.pid, name: first.name, } as ServiceInfo, missing: null as number | null, }; } return { running: null as ServiceInfo | null, missing: port, }; } catch { return { running: null as ServiceInfo | null, missing: port, }; } }) ); const running: ServiceInfo[] = []; const expected_but_missing: number[] = []; for (const check of checks) { if (check.status === "fulfilled") { if (check.value.running) { running.push(check.value.running); } else if (check.value.missing !== null) { expected_but_missing.push(check.value.missing); } } } return { running, expected_but_missing }; } - src/tools/processes.ts:3-7 (schema)Type definitions: ServiceInfo (port, pid, name) and ProcessResult (running[], expected_but_missing[]).
export interface ServiceInfo { port: number; pid: number; name: string; } - src/index.ts:58-73 (registration)Tool registration in ListToolsRequestSchema handler: declares name 'get_running_services', description, and inputSchema (accepts optional cwd).
{ name: "get_running_services", description: "Lists processes running on common dev ports (3000, 4000, 5173, 8080 etc). Shows what is running and what is expected but missing.", inputSchema: { type: "object", properties: { cwd: { type: "string", }, }, }, }, ], }; }); - src/index.ts:136-162 (handler)CallToolRequestSchema handler that dispatches 'get_running_services': detects framework, calls getRunningServices(framework.expectedPorts), returns result as JSON text.
if (toolName === "get_running_services") { try { const args = request.params.arguments as { cwd?: string } | undefined; const cwd = args?.cwd ?? process.cwd(); const framework = await detectFramework(cwd); const result = await getRunningServices(framework.expectedPorts); return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify({ error: `Failed to get running services: ${String(error)}`, }), }, ], }; } } - src/detectors/frameworks.ts:1-66 (helper)Framework detector providing expectedPorts for each framework (Next.js: 3000, Vite: 5173, Express: [3000,8080], FastAPI: 8000, unknown: [3000,8000,8080]).
import { readFile } from "node:fs/promises"; import { join } from "node:path"; export interface FrameworkInfo { framework: "nextjs" | "vite" | "express" | "fastapi" | "unknown"; logPaths: string[]; expectedPorts: number[]; } const UNKNOWN_FRAMEWORK: FrameworkInfo = { framework: "unknown", logPaths: ["logs/"], expectedPorts: [3000, 8000, 8080], }; export async function detectFramework(cwd: string): Promise<FrameworkInfo> { try { const packageJsonPath = join(cwd, "package.json"); const packageJsonRaw = await readFile(packageJsonPath, "utf8"); const packageJson = JSON.parse(packageJsonRaw) as { dependencies?: Record<string, string>; devDependencies?: Record<string, string>; }; const mergedDeps = { ...(packageJson.dependencies ?? {}), ...(packageJson.devDependencies ?? {}), }; if ("next" in mergedDeps) { return { framework: "nextjs", logPaths: [".next/server/"], expectedPorts: [3000], }; } if ("vite" in mergedDeps) { return { framework: "vite", logPaths: ["dist/"], expectedPorts: [5173], }; } if ("express" in mergedDeps) { return { framework: "express", logPaths: ["logs/"], expectedPorts: [3000, 8080], }; } if ("fastapi" in mergedDeps) { return { framework: "fastapi", logPaths: ["logs/"], expectedPorts: [8000], }; } return UNKNOWN_FRAMEWORK; } catch { return UNKNOWN_FRAMEWORK; } }