Files
mcp-windows/src/tools/process.ts
T
Jonathan Miller 03e7ea0e69
Generic: Repo Health / Release configuration (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Access control (push) Has been cancelled
feat: implement v1.0 high-priority tools (14 tools)
Replace template API scaffolding with Windows desktop system tools:

- shell.ts: PowerShell/cmd/bash executor + persistent terminal sessions
- tools/execute.ts: windows_execute (#1)
- tools/process.ts: windows_process_list (#2)
- tools/audio.ts: windows_audio_get, windows_audio_set (#6, #7)
- tools/system.ts: windows_system_info (#18)
- tools/terminal.ts: windows_terminal_start/send/read/list/kill (#35)
- tools/filesystem.ts: windows_file_read/write/edit, windows_search (#36-39)

Removes template API client/config/types (not needed for local OS MCP).

Authored-by: Moko Consulting
2026-05-25 21:03:40 -05:00

81 lines
2.4 KiB
TypeScript

/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Tool: windows_process_list — List running processes (#2)
*/
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { runPowerShell } from '../shell.js';
interface ProcessInfo {
PID: number;
Name: string;
CPU: number;
MemoryMB: number;
WindowTitle: string;
Path: string;
}
export function registerProcessTools(server: McpServer): void {
server.tool(
'windows_process_list',
'List running processes with PID, name, CPU, memory, window title, and path.',
{
filter: z.string().optional().describe('Filter by process name (substring match)'),
sort: z.enum(['cpu', 'memory', 'name']).default('memory').describe('Sort order'),
limit: z.number().default(50).describe('Max results to return'),
},
async ({ filter, sort, limit }) => {
const filterClause = filter
? `| Where-Object { $_.Name -like '*${filter.replace(/'/g, "''")}*' }`
: '';
const sortClause = sort === 'cpu'
? '| Sort-Object CPU -Descending'
: sort === 'name'
? '| Sort-Object Name'
: '| Sort-Object WorkingSet64 -Descending';
const ps = `
Get-Process ${filterClause} ${sortClause} | Select-Object -First ${limit} |
ForEach-Object {
[PSCustomObject]@{
PID = $_.Id
Name = $_.ProcessName
CPU = [math]::Round($_.CPU, 1)
MemoryMB = [math]::Round($_.WorkingSet64 / 1MB, 1)
WindowTitle = $_.MainWindowTitle
Path = $_.Path
}
} | ConvertTo-Json -Depth 3 -Compress`;
const result = await runPowerShell(ps);
if (result.exitCode !== 0) {
return { content: [{ type: 'text', text: `Error: ${result.stderr}` }], isError: true };
}
let processes: ProcessInfo[] = [];
if (result.stdout) {
const parsed = JSON.parse(result.stdout);
processes = Array.isArray(parsed) ? parsed : [parsed];
}
const lines = processes.map(p =>
`${String(p.PID).padStart(7)} ${p.Name.padEnd(25).slice(0, 25)} ${String(p.CPU ?? 0).padStart(8)}s ${String(p.MemoryMB).padStart(8)} MB ${p.WindowTitle || ''}`,
);
const header = `${'PID'.padStart(7)} ${'Name'.padEnd(25)} ${'CPU'.padStart(8)} ${'Memory'.padStart(8)} Window Title`;
const separator = '-'.repeat(90);
return {
content: [{
type: 'text',
text: `${header}\n${separator}\n${lines.join('\n')}\n\n${processes.length} processes`,
}],
};
},
);
}