executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
sap-gui-scriptingSAP GUI Scripting automation — fallback when ADT cannot handle an operation. Navigates transactions, executes BDC, reads ALV grids, handles popups. Use for SPRO, SU01, SM30, SE16, SNOTE, and any transaction ADT cannot run.
Independent GitHub snapshot · Automated classification · Original documentation governs
name: sap-gui-scripting description: >- SAP GUI Scripting automation — fallback when ADT cannot handle an operation. Navigates transactions, executes BDC, reads ALV grids, handles popups. Use for SPRO, SU01, SM30, SE16, SNOTE, and any transaction ADT cannot run. trigger:
When ADT MCP returns "not supported", fall back to SAP GUI Scripting. Uses mario-andreschak/mcp-sap-gui (TypeScript) or kts982/mcp-sap-gui (Python).
sapgui/user_scripting → TRUESAPGUI_HOST, SAPGUI_USER, SAPGUI_PASSWORD, SAPGUI_CLIENT{
"mcp-sap-gui": {
"type": "stdio",
"command": "node",
"args": ["./mcp-sap-gui/dist/index.js"],
"env": {
"SAPGUI_HOST": "${SAPGUI_HOST}",
"SAPGUI_USER": "${SAPGUI_USER}",
"SAPGUI_PASSWORD": "${SAPGUI_PASSWORD}",
"SAPGUI_CLIENT": "${SAPGUI_CLIENT}"
}
}
}
# BDC execution helper (illustrative snippet - adapt into your automation)
import win32com.client
def execute_bdc(session, transaction, bdcdata, mode='N'):
"""Execute BDC recording. mode: N=no display, A=all, E=errors only."""
session.StartTransaction(transaction)
for step in bdcdata:
for field_name, field_value in step.get('fields', {}).items():
try:
session.findById(field_name).text = field_value
except Exception as e:
log_field_skip(field_name, str(e))
if step.get('okcode'):
session.findById('wnd[0]').sendVKey(step['okcode'])
return session
# Example: SM30 table maintenance
BDC_SM30 = [
{'fields': {'wnd[0]/usr/txtVIEW-AREA': 'ZROUTER_TMPL'},
'okcode': '0'} # 0 = Enter
]
session = win32com.client.Dispatch("SapGui.ScriptingCtrl")
connection = session.OpenConnection(SAPGUI_HOST)
execute_bdc(connection.Children(0), 'SM30', BDC_SM30)
# ALV grid reader (illustrative snippet)
def read_alv_grid(session, grid_id='wnd[1]/usr/cntlGRID1/shellcont/shell'):
"""Read ALV grid data. Works for MMBE, MB51, ME2M, VA05, FBL1N, KSB1."""
grid = session.findById(grid_id)
headers = [grid.GetColumnHeader(c) for c in range(grid.ColumnCount)]
rows = []
for r in range(grid.RowCount):
rows.append({headers[c]: grid.GetCellValue(r, c)
for c in range(grid.ColumnCount)})
return rows
# Popup handler (illustrative snippet)
def handle_popup(session, button='OK'):
"""Detect and dismiss modal popup. Returns True if handled."""
try:
popup = session.findById('wnd[1]')
actions = {'OK': 0, 'CANCEL': 12, 'YES': 'btn[0]', 'NO': 'btn[1]'}
act = actions.get(button, 0)
if isinstance(act, int):
popup.sendVKey(act)
else:
popup.findById(act).press()
return True
except Exception:
return False
# Routing strategy (illustrative snippet - real engine: scripts/sap_router.py)
GUI_FALLBACK = [
'SPRO', 'SM30', 'SU01', 'SU53', 'PFCG', 'SNOTE',
'MM01', 'MM02', 'ME21N', 'MIGO', 'MMBE',
'VA01', 'VA02', 'VL01N', 'VF01',
'FB01', 'FB02', 'FS00', 'F110',
'QA01', 'CO01', 'KO01', 'PA20', 'PA30'
]
def route(action, try_adt=True):
"""Route: ADT first → GUI fallback → ZROUTER RFC."""
if try_adt and adt_supports(action):
return {"dest": "ADT", "fallback": "sap-gui-scripting"}
if action.upper() in GUI_FALLBACK:
return {"dest": "SAP GUI", "mcp": "mcp-sap-gui", "tcode": action}
return {"dest": "ZROUTER RFC"}
sapgui/user_scripting is FALSE in RZ11.handle_popup() after every sendVKey in BDC loops.# Primary: cross-platform Python check (recommended — works on Windows and Linux)
python scripts/check_gui_scripting.py --host "$SAPGUI_HOST"
# or: npm run gui:check
# Supplementary: bash-only MCP config check
grep -q '"mcp-sap-gui"' .mcp.json && echo "OK: MCP config found" || echo "FAIL: no config"