Skip to main content
Glama
gbdngb12

procmon-mcp

by gbdngb12
README.md
# Procmon Native MCP

AI가 **실제 Sysinternals Process Monitor**를 쓰는 Windows MCP. GUI 좌표나 Procmon 명령행을 모델이 알 필요 없다.

독립형 캡처·분석 서버. 대상 프로그램 실행·종료·권한 변경 API가 없고, 다른 MCP/실행 도구의 존재를 탐지하거나 호출하지 않는다. Microsoft 서명 Procmon → PID 또는 Process Name 필터 PMC → PML → Procmon 자체 CSV → SQLite 구조다. `procmon-parser`는 PMC 생성에만 사용한다.

## 설치·실행

요구 사항: Windows, uv, Microsoft 서명 Procmon, 관리자 PowerShell, 여유 디스크 2 GiB. Procmon EULA는 먼저 직접 검토·동의하고 Procmon을 닫는다. 설치 스크립트는 EULA를 대신 수락하지 않는다.

```powershell
git clone https://github.com/gbdngb12/procmon-mcp.git
cd .\procmon-mcp
.\install.ps1

# 관리자 PowerShell에서 실행. Procmon 경로 필수.
.\start.ps1 -ProcmonPath 'C:\Tools\ProcessMonitor\Procmon64.exe' `
  -Transport streamable-http -BindHost 127.0.0.1 -Port 8003
```

아래 Procmon 경로는 예시다. 실제 설치 경로로 바꾼다. stdio JSON의 프로젝트 경로도 실제 clone 위치로 바꾼다.

연결 URL: `http://127.0.0.1:8003/mcp`. 다른 PC에서는 그 PC의 `127.0.0.1`이 아니라 Windows 서버 주소로 연결해야 한다.

Python 직접 실행도 같은 조건을 강제한다:

```powershell
.\.venv\Scripts\python.exe -m procmon_native_mcp `
  --procmon-path 'C:\Tools\ProcessMonitor\Procmon64.exe' `
  --transport streamable-http --host 127.0.0.1 --port 8003
```

관리자 권한이 없거나 `--procmon-path`가 없으면 시작하지 않는다. 자동 경로 추측·자동 UAC 승격 없음. 잘못된 파일, Microsoft 서명 검증 실패, EULA 미동의도 거부한다.

설치기는 상위 MCP가 넘긴 `UV_PROJECT_ENVIRONMENT`/`VIRTUAL_ENV`를 격리한다. 이 프로젝트의 `.venv`만 설치 대상으로 사용하고 원래 환경변수는 복원한다.

## 인증

HTTP는 `PROCMON_MCP_AUTH_KEY` 설정 시 Bearer 인증을 사용한다. 32자 이상 난수를 사용한다. 비-loopback 바인딩은 키 없으면 거부한다.

```powershell
# 키를 화면에 출력하지 않고 현재 PowerShell 환경에 생성.
$keyBytes = New-Object byte[] 48
$rng = [Security.Cryptography.RandomNumberGenerator]::Create()
$rng.GetBytes($keyBytes)
$rng.Dispose()
$env:PROCMON_MCP_AUTH_KEY = [Convert]::ToBase64String($keyBytes)

.\start.ps1 -ProcmonPath 'C:\Tools\ProcessMonitor\Procmon64.exe' `
  -Transport streamable-http -BindHost 0.0.0.0 -Port 8003
```

클라이언트 헤더: `Authorization: Bearer <같은 키>`. 관리자 MCP에 접근 권한을 주는 키이므로 안전하게 전달·보관한다. 서버의 일반 HTTP는 암호화되지 않는다. 외부 연결에는 TLS 프록시나 신뢰할 수 있는 터널과 방화벽 제한을 사용한다. 공개 인터넷에 평문 HTTP로 노출하지 않는다. Windows 방화벽 규칙은 설치기가 자동 변경하지 않는다.

## stdio 연결

`--transport` 생략 시 stdio. stdio를 생성하는 클라이언트 프로세스도 관리자 권한이어야 한다. 일반 권한 클라이언트는 별도 관리자 PowerShell에서 실행한 HTTP 서버에 연결하는 방식이 편하다.

```json
{
  "mcpServers": {
    "procmon": {
      "command": "C:\\src\\procmon-mcp\\.venv\\Scripts\\python.exe",
      "args": ["-m", "procmon_native_mcp", "--procmon-path", "C:\\Tools\\ProcessMonitor\\Procmon64.exe"]
    }
  }
}
```

클라이언트별 설정 형식은 다를 수 있다. 이 프로젝트가 Claude/Codex의 기존 연결 설정을 자동 수정하지는 않는다.

## AI 사용 순서

### 이미 실행 중인 프로그램

1. `procmon_status`: 실행 가능 여부·기존 Procmon·복구 필요 여부 확인.
2. `procmon_find_processes(name="app.exe")`: PID 선택. `child_pids` 확인. Python/uv/git 실행기 PID와 실제 작업 PID가 다를 수 있다.
3. `procmon_start_capture(pids=[1234], duration_seconds=15)`: 기본 최대 8초 준비 대기. `state="capturing"`일 때만 대상 작업 수행. `starting`이면 `procmon_get_capture(..., wait_seconds=3)`.
4. 다른 GUI/프로그램 도구로 진단할 동작 수행.
5. `procmon_stop_capture(capture_id=...)`: 기본 최대 8초 종료·내보내기 대기. `completed`가 아니면 `procmon_get_capture`로 확인. 자동 시간 종료도 지원.
6. `procmon_summarize_capture(capture_id=...)`: 기본 종합 요약. 작업·결과 상위 값, 쓰기·접근 거부·없는 경로 건수를 한 번에 확인.
7. `procmon_query_events(capture_id=..., focus="missing", path_contains="config", limit=20)`: 필요한 행만. `focus`는 all/writes/access_denied/missing. 계속 읽을 때 응답의 `next_offset` 사용.

핵심 사용성: 상태·다음 행동 명시, 중복 시작 차단, 종료 재호출 안전, 실제 MCP 오류 플래그, 스키마 범위 검증, Unicode 경로 검색, 응답량 제한, 빈 로그 경고.

### 아직 실행하지 않은 프로그램 관측

PID 대신 이름으로 먼저 캡처한다. 아래는 MCP 도구 호출 인자이며 PowerShell 명령이 아니다.

```json
{
  "process_names": ["app.exe"],
  "duration_seconds": 30
}
```

1. `procmon_start_capture`에 위 인자 전달. `pids`와 `process_names`는 정확히 하나만 지정한다.
2. `state="capturing"` 확인. `starting`이면 `procmon_get_capture(..., wait_for="ready", wait_seconds=10)`로 대기.
3. **호출자가 독립적으로** 앱을 실행하거나 동작을 수행한다. 서버는 실행 주체·방법·권한을 모르며 실행 요청도 보내지 않는다.
4. `procmon_stop_capture` 또는 시간 만료 → `completed` 확인 → 요약·조회.
5. 같은 이름의 여러 PID가 보이면 `procmon_summarize_capture(group_by="pid")` 또는 `get_capture.observed_processes`로 확인하고, `procmon_query_events(pid=...)`로 조회를 좁힌다.

| start_capture 인자 | 의미 |
|---|---|
| `pids` | 기존 PID 1~8개. 이름 모드와 동시 지정 불가 |
| `process_names` | 정확한 프로세스 이름 1~8개. 대소문자 무시. 아직 존재하지 않아도 됨. 경로·와일드카드 불가 |
| `duration_seconds` | 기본 15초, 1~120초. 이름 모드는 준비 완료부터 측정하며 앱이 나타날 때까지 타이머를 멈추지 않음 |
| `max_log_mb` | 기본 64 MiB, 최종 PML 예산 32~256 MiB |
| `wait_seconds` | 기본 8초, 0~10초. 도구 응답 대기이며 캡처 제한 시간이 아님 |

이름 모드는 **같은 이름의 기존·새 인스턴스 모두**를 포함한다. 파일 경로가 다른 동명 EXE도 구분하지 않는다. 자식·부모는 자동 추가하지 않으며, 지정한 이름에 맞을 때만 포함한다. 원본 PML/CSV/SQLite 모두 같은 이름 범위다. 조회의 PID 필터는 저장된 원본 범위를 바꾸지 않는다.

완료 후 `startup_evidence`는 전체 CSV의 Process Create/Start/Load Image/Exit 건수다. 인덱스 한도·요약 필터와 독립적이다. **Process Create는 생성 요청자에 기록된다.** 대상의 생성 이벤트는 부모 이름이 범위 밖이면 빠질 수 있고, 잡힌 Create는 대상이 자기 자식을 생성한 이벤트일 수도 있다. PID·Path·Detail을 확인한다. 대상의 시작은 Process Start와 초기 파일 접근으로 확인한다. 마커가 있어도 무손실 수집을 보장하지 않는다. 아무 대상도 나타나지 않으면 빈 캡처와 품질 경고를 반환한다.

**권한:** 이 서버는 Procmon 제어 때문에 관리자 권한을 유지한다. 대상 프로그램의 권한은 독립적인 실행 주체가 결정한다. 서버는 로그인 사용자 토큰을 얻거나 전달하지 않고 대상을 승격·강등하지도 않는다. `stop_capture`·시간 만료·서버 종료는 대상 프로그램을 종료하지 않는다.

이전 `procmon_launch_capture` API와 실행 코드는 삭제했다. 호환 별칭도 없다. 기존 서버 프로세스는 재시작하고 클라이언트의 도구 목록을 갱신해야 한다. 도구 수는 9개다.

| 도구 | 역할 |
|---|---|
| `procmon_status` | 설치·권한·진행 상태·최근 캡처 |
| `procmon_find_processes` | 정확한 이름/부분 이름, 부모·자식 PID 탐색 |
| `procmon_start_capture` | PID 또는 이름 1~8개, 자동 종료 캡처 |
| `procmon_get_capture` | 비동기 단계·결과·복구 안내 |
| `procmon_stop_capture` | 자기 캡처만 종료·내보내기 |
| `procmon_summarize_capture` | operation/result/path/process/pid 집계 |
| `procmon_query_events` | 정확한 operation/result/PID + 경로 부분 검색, 페이지 조회 |
| `procmon_compare_captures` | 두 캡처의 단순 건수 차이 |
| `procmon_recover_settings` | 중단 후 남은 설정 백업의 명시적 복구 |

`operation`/`result`는 정확한 값, `path_contains`는 대소문자 무시 리터럴 부분 문자열이다. 필터끼리는 AND. 정규식·임의 SQL·임의 프로그램/셸 실행 API 없음.

## 제한·주의

- 기존 Procmon이 있으면 거부. 전역 `/Terminate` 사용 안 함. 직접 생성한 Procmon PID의 창만 정상 종료한다.
- 조기 종료 시 내부 버퍼 전달을 위해 1초 대기 후 닫는다. AI가 별도 sleep을 넣을 필요는 없다. 이 유예는 검증된 짧은 작업의 누락을 줄이지만, 모든 부하에서 무손실 수집을 보장하지 않는다.
- 기존 Procmon 레지스트리 설정을 백업하고 종료·내보내기 후 검증하여 복원한다. 복원 실패 시 백업 유지, 다음 캡처 차단. `recover_settings`는 백업 이후 수동 설정 변경도 덮어쓰므로 영향을 확인한 뒤 호출한다.
- PID 모드는 시작 시 지정한 고정 PID, 이름 모드는 수집 중 이름에 맞는 모든 인스턴스. 과거 이벤트 소급 수집 없음. PID 모드의 재사용 검사는 샘플링이므로 극히 짧은 구간의 완전 차단을 보장하지 않는다. 이름 모드의 PID별 결과도 서로 다른 실행의 재사용 PID를 자동으로 단일 lifetime으로 구분하지 않는다.
- 1~120초. 기본 15초. 원시 로그·설정 파일은 로컬 저장. `%LOCALAPPDATA%\ProcmonNativeMCP\captures`, 또는 `--data-dir`/`PROCMON_MCP_DATA`로 변경.
- `max_log_mb`는 **정상 종료 후 PML 크기** 제한(32~256 MiB, 기본 64). Procmon은 live backing 파일을 선할당한다. 별도 1 GiB live-file 한도를 100 ms마다 확인하며 종료 지연으로 초과할 수 있다. 2 GiB 여유 디스크 요구. 로그 디렉터리 2 GiB 예산 사전 검사도 엄격한 디스크 쿼터는 아니다.
- CSV는 PML의 4배 예산, 내보내기 90초 제한. 인덱스 최대 200,000행. 범위 검증은 인덱스 한도 이후 CSV 행도 확인한다. 초과 여부 `index_truncated` 명시.
- 페이지 최대 200행. 기본 응답 24,000자 예산. 긴 필드는 잘림 표시. 집계도 전체가 아닌 상위 N개면 `truncated` 표시.
- 이름 모드에는 같은 이름의 다른 프로세스 이벤트도 저장된다. 모든 PML에는 추가 프로세스 메타데이터가 포함될 수 있다. 원본·경로·상세에는 민감 정보가 들어갈 수 있으므로 외부 공유 전 검토한다.
- `NAME NOT FOUND`, `BUFFER OVERFLOW`는 정상 탐색에서도 발생한다. 빈 로그는 안전하다는 증거가 아니다. 요약·건수 차이만으로 취약점이나 원인을 단정하지 않는다.
- 설치된 Procmon 4.01/Windows x64를 검증 대상으로 사용한다. 다른 버전·아키텍처·CSV 스키마는 추가 검증 필요. Procmon 자체는 배포하지 않는다.

## 검증 재실행

```powershell
.\.venv\Scripts\python.exe -m pytest -q
.\.venv\Scripts\python.exe scripts\live_verify.py `
  --procmon-path 'C:\Tools\ProcessMonitor\Procmon64.exe'
.\.venv\Scripts\python.exe scripts\http_verify.py `
  --procmon-path 'C:\Tools\ProcessMonitor\Procmon64.exe'
# 이름 모드 실검증: 자체 fixture를 먼저 컴파일. 실행은 별도 테스트 클라이언트만 수행.
New-Item -ItemType Directory -Path test-results\fixtures -Force | Out-Null
& "$env:WINDIR\Microsoft.NET\Framework64\v4.0.30319\csc.exe" /nologo /target:exe /codepage:65001 /out:test-results\fixtures\ProcmonCaptureOnlyProbe.exe scripts\name_fixture.cs
.\.venv\Scripts\python.exe scripts\name_verify.py `
  --procmon-path 'C:\Tools\ProcessMonitor\Procmon64.exe' `
  --fixture-exe 'test-results\fixtures\ProcmonCaptureOnlyProbe.exe' `
  --output 'test-results\names'
```

실캡처 스크립트끼리는 동시에 실행하지 않는다. 테스트는 직접 만든 프로세스·임시 폴더·임시 레지스트리 키만 사용한다. 생성한 로그·테스트 폴더는 근거 보존을 위해 자동 삭제하지 않는다.

## 근거

- [Microsoft Process Monitor](https://learn.microsoft.com/en-us/sysinternals/downloads/procmon)
- [procmon-parser: PMC 포맷](https://github.com/eronnen/procmon-parser/blob/main/docs/PMC%20Format.md) — 역공학 포맷이므로 실제 Procmon 동작 검증 필수.
- [Git check-ignore](https://git-scm.com/docs/git-check-ignore), [gitignore](https://git-scm.com/docs/gitignore) — Git 사용성 사례의 기대 동작. Ignore는 비밀정보 보호 경계가 아니며 이미 추적된 파일에는 적용되지 않는다.

Maintenance

ActivityMaintained
ResponsivenessNo issues