SAP ABAP File System - ABAP Writer 개발 고찰 (NW 7.4 이하)

1. 개발 목적

배경

SAP ABAP 개발 환경에서 AI 어시스턴트(Claude Code)를 활용하여 소스 코드를 읽고, 분석하고, 수정할 수 있다면 개발 생산성을 크게 높일 수 있다.

현재 VS Code 계열 에디터(VS Code, Antigravity 등)에서는 abap-fs 확장을 통해 SAP 시스템의 ABAP 오브젝트를 가상 파일시스템(adt://)으로 마운트하고, MCP(Model Context Protocol) 서버를 통해 AI가 읽기 작업은 수행할 수 있다.

그러나 쓰기(저장) 는 제한적이다. 특히 GitHub Copilot은 VS Code Language Model Tool API를 통해 가상 파일시스템에 직접 쓸 수 있지만, Claude Code 같은 외부 AI 도구는 MCP 프로토콜로만 통신하므로 이 경로에 접근할 수 없다.

목표

Claude Code가 ABAP 소스 코드를 수정하고 SAP에 저장할 수 있는 MCP 브리지 확장을 개발한다.

Claude Code
AI Agent
MCP (HTTP)
abap-writer
VS Code 확장
SAP ADT / GUI
SAP 시스템
NW 7.40

개발 환경

항목
SAP NetWeaver 릴리즈7.40 (ECC)
에디터Antigravity (VS Code 포크, 내부 엔진 v1.107)
AI 도구Claude Code (Anthropic, Opus 모델)
MCP 서버abap-fs (HTTP, localhost:4847), mcp-abap-adt (stdio)
OSWindows 11 Pro

2. 개발 내용

아키텍처 변천

개발 과정에서 아키텍처는 3차례 변경되었다.

1ADT REST API 직접 쓰기실패

Claude Code → MCP → abap-writer → ADT REST → SAP

Lock (POST) → Write (PUT) → Unlock
❌ "invalid lock handle" 에러

2abap-adt-api npm 패키지실패

Claude Code → MCP → abap-writer → abap-adt-api → SAP

동일한 Lock/Write 시퀀스
❌ 동일한 에러 (서버 측 버그)

3SAP GUI 자동화성공

Claude Code → MCP → abap-writer (VS Code 확장)

📖 ADT REST → SAP (읽기 전용)
✏️ PowerShell → Win32 API → SAP GUI
Ctrl+A → Del → Ctrl+V → Ctrl+S → Ctrl+F3

제공된 MCP 도구 (최종 버전)

도구용도통신 방식
abap_read_sourceSAP 소스 읽기ADT REST (항상 동작)
modify_buffer에디터 버퍼 수정 (DIRTY, 미저장)VS Code API
replace_in_buffer에디터 버퍼 내 문자열 치환VS Code API
preview_diff버퍼 vs SAP 소스 비교ADT REST + VS Code API
sync_to_sapguiSAP GUI를 통해 저장/활성화PowerShell + SendKeys
check_activation활성화 상태 확인ADT REST
syntax_check구문 체크ADT REST
buffer_status버퍼 열림/DIRTY 상태 확인VS Code API

SAP GUI 자동화 모드

모드동작
manual (추천)사용자가 SE38 편집 모드 직접 진입, 스크립트는 붙여넣기/저장/활성화만
checkpoint기존 로그인 세션 탐지 후 /nse38로 네비게이션, 각 단계 확인창
full_autocheckpoint와 동일하지만 확인창 없음 (위험)
clipboard_only클립보드 복사만, 나머지 수동

프로젝트 폴더/파일 구조

📁abap-writer/v0.1.0
src소스 코드TypeScript + PowerShell
extension.tsVS Code 확장 진입점 — MCP 서버를 localhost:4848/mcp에서 자동 시작, 커맨드 등록
mcpServer.tsJSON-RPC MCP 프로토콜 + 8개 도구 핸들러 + abap-adt-api 클라이언트 + PS 스크립트 spawn
sync_sapgui.ps1Win32 API(C# P/Invoke)로 SAP GUI 창 탐색/포커스, SendKeys 자동화
dist컴파일 결과gitignore
extension.jstsc 컴파일 결과
mcpServer.jstsc 컴파일 결과
sync_sapgui.ps1src/에서 복사됨
skillsClaude Code Skill 파일의사결정 가이드
skill-modify-abap.mdABAP 수정 워크플로우
skill-save-to-sap.mdSAP GUI 저장 워크플로우 (4가지 모드)
skill-fix-errors.md에러 복구 워크플로우 (구문 에러, DUMP)
scripts빌드/배포 스크립트
build-dist.ps1배포 zip 생성 스크립트
.envSAP 연결 정보로컬 전용
.env.example.env 템플릿 (배포용)
package.json확장 매니페스트
tsconfig.jsonTypeScript 설정
.vscodeignorevsix 패키징 제외
.gitignoreGit 추적 제외
CLAUDE.md / _KO.md스킬 가이드
README.md / _KO.md사용 가이드
DISTRIBUTION.md / _KO.md배포 가이드

설치 시 파일 배치

vsix 패키지에는 node_modules.env포함되지 않는다. 설치 후 수동 세팅 필요:

~/.antigravity/extensions/local.abap-writer-0.1.0/

vsixdist/extension.js, mcpServer.js, sync_sapgui.ps1
vsixskills/워크플로우 가이드
vsixpackage.json
수동.env사용자가 직접 생성 (SAP 연결 정보)
수동node_modules/npm install --production (abap-adt-api)

3. 개발 시행착오

3.1 ADT REST API 직접 쓰기

시도: CSRF 토큰 획득 후, Lock(POST ?_action=LOCK) → Write(PUT /source/main?lockHandle=...) → Unlock 시퀀스로 소스 저장.

결과:

Resource INCLUDE <PROGRAM_NAME> is not locked (invalid lock handle: <HEX>)

Lock은 성공하고 Handle도 정상 반환되지만, 이어지는 Write 요청에서 동일한 Handle이 "invalid"로 거부됨.

조사 내용:

  • 쿠키(SAP_SESSIONID, MYSAPSSO2) 정상 유지 확인
  • X-sap-adt-sessiontype: stateful 헤더 모든 요청에 포함
  • HTTP keep-alive Agent 사용으로 TCP 연결 재사용
  • sap-contextid 헤더 캡처 및 재전송
  • Lock URL 변형 시도 (program URL / include URL / source/main URL)
  • 오브젝트 메타데이터에서 abapsource:sourceUri 파싱하여 정확한 URL 사용

모든 변형에서 동일한 에러 발생.

3.2 abap-adt-api npm 패키지 전환

시도: abap-fs가 내부적으로 사용하는 abap-adt-api 패키지를 직접 임포트하여 검증된 코드로 Lock/Write 수행.

1const client = new ADTClient(url, user, password, client, language, sslConfig);
2client.stateful = session_types.stateful;
3await client.login();
4
5const structure = await client.objectStructure(programUrl);
6const sourceUrl = ADTClient.mainInclude(structure);
7const lock = await client.lock(sourceUrl);
8await client.setObjectSource(sourceUrl, newSource, lock.LOCK_HANDLE);

결과: 동일한 에러. 라이브러리는 정상이며 문제는 서버 측에 있음을 확인.

3.3 SAP GUI Scripting (COM) 시도

시도: Windows COM 인터페이스로 SAP GUI 스크립팅 엔진에 접근.

1$rot = New-Object -ComObject 'SapROTWr.SapROTWrapper'
2$gui = $rot.GetROTEntry('SAPGUI')
3$app = $gui.GetScriptingEngine()  # ← 실패

결과: TYPE_E_CANTLOADLIBRARY (0x80029C4A) — 서버 프로파일 파라미터 sapgui/user_scriptingFALSE 설정.

클라이언트 측 스크립팅은 활성화되어 있었으나, 서버 측 설정 변경은 BASIS 관리자만 가능하여 포기.

3.4 UI Automation — AppActivate 실패

시도: PowerShell의 AppActivate(PID) + SendKeys로 SAP GUI 창에 키 입력.

문제:

  • Windows 10/11에서 AppActivate의 Foreground 전환이 불안정
  • saplogon.exe가 여러 자식 창(로그인 선택기, Easy Access, 트랜잭션 세션)을 호스팅하여 PID만으로 타겟팅 모호
  • SendKeys가 엉뚱한 창(에디터)으로 전달되는 현상

3.5 Win32 API 직접 호출 — 성공

해결: PowerShell 내 C# 인라인 코드로 Win32 API를 P/Invoke:

EnumWindows
모든 최상위 창 열거
GetWindowText
제목으로 SAP 세션 창 매칭
ShowWindow
최소화 복원
SetForegroundWindow
BringWindowToTop + AttachThreadInput으로 확실한 포커스 이동

3.6 기타 이슈들

이슈원인해결
PowerShell 한글 깨짐PS 5.1이 스크립트를 CP949로 읽음 (UTF-8이 아닌)키워드를 ASCII 전용으로 변경
C# out _ 구문 에러PS 5.1의 C# 컴파일러가 C# 7.0 미지원out uint tempPid로 명시적 선언
MessageBox 안 보임windowsHide: true로 spawn + 관리자 권한 에디터windowsHide: false 변경
잘못된 창 선택여러 SAP 시스템 연결 시 다른 시스템 창 선택ListBox UI 추가 + 세션 패턴 우선 정렬
sapshcut 로그인 대화상자 오인식sapshcut가 미로그인 시 로그인 창을 띄움sapshcut 제거, 기존 세션에서 /nse38로 네비게이션

4. ABAP-FS에서의 CREATE OBJECT vs EDIT 차이

흥미로운 발견

개발 과정에서 중요한 사실이 확인되었다:

  • abap-fs의 "ABAP Create Object" 기능으로 새 INCLUDE를 생성하면 SAP에 정상 저장
  • abap-fs의 활성화 기능도 정상 동작
  • 하지만 이미 존재하는 오브젝트의 소스 수정 후 Ctrl+S동일한 Lock 에러로 실패

원인 분석

이 차이는 ADT REST API의 엔드포인트별 동작 방식에 기인한다:

CREATE (생성)✅ 정상
POST /sap/bc/adt/programs/includes
  • 오브젝트 미존재 → Lock 불필요
  • 1회 요청으로 생성 + 초기 소스 저장
  • 세션 연속성 불필요
1-step 작업
ACTIVATE (활성화)✅ 정상
POST /sap/bc/adt/activation
  • 저장된 소스 상태만 변경 (inactive → active)
  • 소스 내용 수정 아님, Lock 불필요
  • 1회 요청
1-step 작업
WRITE (소스 수정)❌ 실패
1. POST /source/main?_action=LOCK → Handle 반환
2. PUT /source/main?lockHandle=…invalid
3. POST /source/main?_action=UNLOCK
  • 기존 오브젝트 수정 → Lock Handle 필수
  • 2개 요청 간 세션 연속성 필요
  • NW 7.40 ICM의 Handle 검증 버그
2-step 작업 — Lock Handle 깨짐

핵심 결론

Lock Handle을 필요로 하는 2-step 작업(Lock → Write)에서만 실패가 발생하며, 1-step 작업(Create, Activate)은 정상 동작한다. 이는 NW 7.40의 ADT REST 서버에서 stateful 세션 간 Lock Handle 검증 로직이 불완전하기 때문이다.

SAP GUI에서는 이 문제가 발생하지 않는다. SAP GUI는 ADT REST API가 아닌 DIAG 프로토콜 (SAP 전용 바이너리 프로토콜)을 사용하며, 자체적인 Lock 메커니즘(SM12 enqueue)을 직접 호출하기 때문이다.

5. 부록 (참고)

Language Model Tool vs MCP Tool

구분Language Model ToolMCP Tool
통신 방식VS Code 내부 APIHTTP / stdio 외부 통신
사용 가능한 AIGitHub Copilot (VS Code 내장)Claude Code, Cursor 등 외부 도구
가상 파일시스템 쓰기가능 (replace_string_in_file)불가능
정의 위치확장의 package.jsonlanguageModelToolsMCP 서버 구현체

abap-fs 확장은 Language Model Tool을 39개 이상 정의하여 Copilot에게 ABAP 편집 기능을 제공한다. 하지만 MCP를 통한 외부 AI 도구에는 읽기 전용 기능만 노출된다.

SAP NetWeaver 버전별 ADT 쓰기 지원

NW 버전ADT REST 읽기ADT REST 쓰기비고
7.40OXabapfs_extensions 설치 시 가능
7.50OXabapfs_extensions 설치 시 가능
7.51+OO네이티브 지원
S/4HANAOO완전 지원

abapfs_extensions 플러그인

GitHub: marcellourbani/abapfs_extensions

NW 7.40/7.50에서 누락된 ADT 쓰기 엔드포인트를 패치하는 ABAP 애드온. SAP 서버에 설치하면 abap-fs의 Ctrl+S 저장 및 ADT REST API를 통한 직접 쓰기가 가능해진다. BASIS 관리자 설치 필요.

SAP GUI Scripting vs UI Automation (SendKeys)

항목SAP GUI ScriptingUI Automation (SendKeys)
서버 설정 필요예 (sapgui/user_scripting=TRUE)불필요
정밀도높음 (오브젝트 모델 접근)중간 (키 시퀀스 의존)
권한 필요S_SCR_CHT없음
창 제어COM 인터페이스Win32 API (P/Invoke)
NW 버전 의존없음없음
안정성높음포커스 관리에 의존

기술 스택

기술용도
TypeScriptVS Code 확장 (MCP HTTP 서버, 버퍼 수정 로직)
PowerShell 5.1SAP GUI 자동화 스크립트 (Win32 API, SendKeys)
C# (인라인)PowerShell 내 Win32 P/Invoke 정의
abap-adt-api (npm)SAP ADT REST API 클라이언트 (읽기 전용 활용)
Node.js child_processPowerShell 스크립트 실행

6. 개발 폐기 사유

폐기 결정 배경

본 프로젝트(abap-writer)는 SAP NetWeaver 7.40 환경의 ADT REST API 쓰기 제한을 우회하기 위해 개발되었다.

그러나 다음과 같은 이유로 개발을 폐기하고 기록으로 남긴다:

1. 근본 원인이 SAP 서버 버전에 있음

ADT REST API의 Lock/Write 2-step 시퀀스 실패는 NW 7.40의 서버 측 버그이다. 클라이언트 측에서 아무리 정교하게 구현해도 서버가 Lock Handle을 거부하는 한 해결 불가.

2. NW 버전 업그레이드 예정

조직의 PI(Process Innovation) 프로젝트에 따라 SAP 시스템이 상위 NW 버전(7.51+ 또는 S/4HANA)으로 업그레이드될 예정이다. 업그레이드 완료 후에는:

  • ADT REST API 쓰기가 네이티브로 동작
  • abap-fs의 Ctrl+S 저장이 정상 동작
  • abap-adt-api를 통한 직접 쓰기도 가능
  • SAP GUI 자동화라는 우회 경로가 불필요

3. SAP GUI 자동화의 태생적 한계

SAP GUI UI Automation(SendKeys)은 동작하지만 다음과 같은 한계가 있다:

  • 포커스 의존적: 자동화 중 다른 창 클릭 시 실패
  • 환경 의존적: SAP GUI 버전, 화면 해상도, 언어 설정에 따라 키 시퀀스 다를 수 있음
  • 감사(Audit) 어려움: 자동화 키 입력은 수동 입력과 구분 불가
  • 프로덕션 부적합: 테스트/개발 용도로만 사용 가능

4. 업그레이드 후 대안

NW 7.51+ 또는 S/4HANA 환경에서는 다음 2가지 접근이 모두 유효해진다:

방법 AFileSystemProvider

abap-fs의 FileSystemProvider + Language Model Tool
Copilot이 직접 가상 파일시스템에 쓰기 가능

현재 Copilot에서만 동작
방법 BMCP + ADT REST API

MCP 서버에서 abap-adt-api를 통한 직접 쓰기
Claude Code 등 외부 AI 도구에서 직접 Lock/Write 가능

SAP GUI 자동화 불필요

보존 가치

본 프로젝트의 코드와 문서는 다음과 같은 참고 가치를 가진다:

  • ADT REST API의 동작 방식과 NW 버전별 차이에 대한 실증적 기록
  • VS Code 확장에서 MCP HTTP 서버를 구현하는 패턴 (Node.js 기반)
  • **Windows UI Automation (Win32 API + SendKeys)**을 PowerShell에서 활용하는 방법
  • SAP GUI Scripting COM 접근 방법과 한계
  • NW 구형 환경에서 ADT 쓰기를 우회하는 실용적 방법론

본 문서는 개발 과정의 고찰을 기록한 것이며, 해당 확장의 소스 코드는 로컬 저장소에 보관된다.