ktern-sapguimcp 1.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. ktern_sapguimcp-1.0.2/.env.example +35 -0
  2. ktern_sapguimcp-1.0.2/.gitattributes +16 -0
  3. ktern_sapguimcp-1.0.2/.gitignore +122 -0
  4. ktern_sapguimcp-1.0.2/.gitmodules +6 -0
  5. ktern_sapguimcp-1.0.2/.prettierrc +9 -0
  6. ktern_sapguimcp-1.0.2/ARCHITECTURE.md +262 -0
  7. ktern_sapguimcp-1.0.2/CONTRIBUTING.md +307 -0
  8. ktern_sapguimcp-1.0.2/Dockerfile +50 -0
  9. ktern_sapguimcp-1.0.2/LICENSE +21 -0
  10. ktern_sapguimcp-1.0.2/PKG-INFO +777 -0
  11. ktern_sapguimcp-1.0.2/PUBLISHING.md +175 -0
  12. ktern_sapguimcp-1.0.2/README.md +717 -0
  13. ktern_sapguimcp-1.0.2/docker-compose.yml +27 -0
  14. ktern_sapguimcp-1.0.2/docs/SAP_TEST_PREREQUISITES.md +156 -0
  15. ktern_sapguimcp-1.0.2/docs/bulk-operations-performance.md +133 -0
  16. ktern_sapguimcp-1.0.2/docs/design/sap-quick-report-design.md +421 -0
  17. ktern_sapguimcp-1.0.2/docs/design/sap-quick-report-implementation-plan.md +1166 -0
  18. ktern_sapguimcp-1.0.2/docs/plans/2024-12-19-utilities-consulting-ai-tools-design.md +396 -0
  19. ktern_sapguimcp-1.0.2/docs/plans/2026-01-02-js-extraction-design.md +109 -0
  20. ktern_sapguimcp-1.0.2/docs/plans/2026-01-02-pydantic-tool-results-design.md +445 -0
  21. ktern_sapguimcp-1.0.2/docs/plans/2026-01-02-sap-fill-form-design.md +184 -0
  22. ktern_sapguimcp-1.0.2/docs/plans/2026-01-03-github-feedback-issues-design.md +109 -0
  23. ktern_sapguimcp-1.0.2/docs/plans/2026-01-03-intent-logging-design.md +204 -0
  24. ktern_sapguimcp-1.0.2/docs/plans/2026-01-04-dropdown-support-design.md +148 -0
  25. ktern_sapguimcp-1.0.2/docs/plans/2026-01-04-popup-handling-design.md +107 -0
  26. ktern_sapguimcp-1.0.2/docs/plans/2026-01-04-workflow-learning-design.md +374 -0
  27. ktern_sapguimcp-1.0.2/docs/plans/2026-01-05-popup-semantics-design.md +108 -0
  28. ktern_sapguimcp-1.0.2/docs/plans/2026-01-05-tool-capabilities-discovery-design.md +114 -0
  29. ktern_sapguimcp-1.0.2/docs/plans/2026-01-08-se11-lookup-tool-design.md +167 -0
  30. ktern_sapguimcp-1.0.2/docs/plans/2026-01-08-se16-data-browser-design.md +206 -0
  31. ktern_sapguimcp-1.0.2/docs/plans/2026-01-09-typed-test-helpers-design.md +136 -0
  32. ktern_sapguimcp-1.0.2/docs/plans/2026-01-09-typed-test-helpers.md +1124 -0
  33. ktern_sapguimcp-1.0.2/docs/plans/2026-01-12-fm-class-catalog-design.md +176 -0
  34. ktern_sapguimcp-1.0.2/docs/plans/2026-01-14-multi-session-implementation.md +1493 -0
  35. ktern_sapguimcp-1.0.2/docs/plans/2026-01-14-multi-session-support-design.md +319 -0
  36. ktern_sapguimcp-1.0.2/docs/plans/2026-01-21-agent-session-binding-design.md +152 -0
  37. ktern_sapguimcp-1.0.2/docs/plans/2026-01-21-agent-session-binding-impl.md +1177 -0
  38. ktern_sapguimcp-1.0.2/docs/plans/2026-01-23-abapgit-api-pull-design.md +231 -0
  39. ktern_sapguimcp-1.0.2/docs/plans/2026-01-27-mcp-prompts-design.md +85 -0
  40. ktern_sapguimcp-1.0.2/docs/plans/2026-02-13-logging-improvements-design.md +103 -0
  41. ktern_sapguimcp-1.0.2/docs/plans/2026-02-13-logging-improvements-plan.md +1002 -0
  42. ktern_sapguimcp-1.0.2/docs/plans/2026-02-13-onboarding-prompts-design.md +142 -0
  43. ktern_sapguimcp-1.0.2/docs/plans/2026-02-13-onboarding-prompts-plan.md +828 -0
  44. ktern_sapguimcp-1.0.2/docs/plans/2026-02-18-exe-bundling-design.md +174 -0
  45. ktern_sapguimcp-1.0.2/docs/plans/2026-02-18-exe-bundling-plan.md +462 -0
  46. ktern_sapguimcp-1.0.2/docs/plans/2026-02-18-sap-identity-log-correlation-design.md +95 -0
  47. ktern_sapguimcp-1.0.2/docs/plans/2026-02-18-sap-identity-log-correlation-plan.md +579 -0
  48. ktern_sapguimcp-1.0.2/docs/plans/2026-02-19-default-browser-mode-connect-design.md +26 -0
  49. ktern_sapguimcp-1.0.2/docs/plans/2026-02-19-pat-validation-design.md +95 -0
  50. ktern_sapguimcp-1.0.2/docs/plans/2026-02-19-pat-validation-plan.md +451 -0
  51. ktern_sapguimcp-1.0.2/docs/plans/2026-02-20-readme-env-vars-fix-design.md +85 -0
  52. ktern_sapguimcp-1.0.2/docs/plans/2026-02-20-readme-env-vars-fix-plan.md +429 -0
  53. ktern_sapguimcp-1.0.2/docs/plans/2026-02-20-se38-edit-tool-design.md +111 -0
  54. ktern_sapguimcp-1.0.2/docs/plans/2026-02-20-se38-edit-tool-plan.md +693 -0
  55. ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-general-purpose-tools-design.md +422 -0
  56. ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-se09-transport-tool-plan.md +1326 -0
  57. ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-slg1-tool-plan.md +1330 -0
  58. ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-sm30-tool-plan.md +1612 -0
  59. ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-sm37-tool-plan.md +1646 -0
  60. ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-st22-tool-plan.md +1786 -0
  61. ktern_sapguimcp-1.0.2/docs/plans/2026-02-24-sm30-finish-and-spro-search-plan.md +625 -0
  62. ktern_sapguimcp-1.0.2/docs/plans/2026-02-24-sm30-spro-search-design.md +112 -0
  63. ktern_sapguimcp-1.0.2/docs/plans/2026-02-26-abapgit-list-repos-design.md +63 -0
  64. ktern_sapguimcp-1.0.2/docs/plans/2026-02-26-abapgit-list-repos-plan.md +573 -0
  65. ktern_sapguimcp-1.0.2/docs/plans/2026-03-02-remove-sampling-design.md +73 -0
  66. ktern_sapguimcp-1.0.2/docs/plans/2026-03-02-remove-sampling-plan.md +372 -0
  67. ktern_sapguimcp-1.0.2/docs/plans/2026-03-03-abapgit-pull-status-bar-fix-design.md +52 -0
  68. ktern_sapguimcp-1.0.2/docs/plans/2026-03-03-abapgit-pull-status-bar-fix-plan.md +348 -0
  69. ktern_sapguimcp-1.0.2/docs/plans/2026-03-04-ui-backend-abstraction-design.md +259 -0
  70. ktern_sapguimcp-1.0.2/docs/plans/2026-03-04-ui-backend-abstraction-plan.md +1504 -0
  71. ktern_sapguimcp-1.0.2/docs/plans/2026-03-11-stateless-selection-screens-design.md +502 -0
  72. ktern_sapguimcp-1.0.2/docs/plans/2026-03-11-stateless-selection-screens-plan.md +1634 -0
  73. ktern_sapguimcp-1.0.2/docs/plans/PLAN_TRANSACTION_CATALOG.md +267 -0
  74. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-12-protocol-cleanup-plan.md +878 -0
  75. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-14-pysapgui-library.md +3895 -0
  76. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-15-desktop-backend-phase1.md +1285 -0
  77. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-16-desktop-tools-remaining.md +293 -0
  78. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-17-desktop-multi-session.md +279 -0
  79. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-18-readme-desktop-backend.md +363 -0
  80. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-20-pysapgui-open-source-readiness.md +1600 -0
  81. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-24-reduce-local-imports.md +395 -0
  82. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-04-04-popup-rework-active-window.md +886 -0
  83. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-04-05-full-depth-element-info.md +776 -0
  84. ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-04-07-sap-fill-form-desktop-perf.md +1070 -0
  85. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-12-protocol-cleanup-design.md +146 -0
  86. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-13-backend-encapsulation-design.md +271 -0
  87. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-14-pysapgui-library-design.md +545 -0
  88. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-14-sapgui-login-fixture-design.md +204 -0
  89. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-15-desktop-backend-adapter-design.md +295 -0
  90. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-16-com-evaluate-tool-design.md +131 -0
  91. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-17-desktop-multi-session-design.md +126 -0
  92. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-18-readme-desktop-backend-design.md +106 -0
  93. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-20-pysapgui-open-source-readiness-design.md +186 -0
  94. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-24-architecture-docs-design.md +29 -0
  95. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-24-reduce-local-imports-design.md +124 -0
  96. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-24-test-gating-design.md +47 -0
  97. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-04-04-popup-rework-active-window-design.md +262 -0
  98. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-04-05-full-depth-element-info-design.md +206 -0
  99. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-04-07-sap-fill-form-desktop-perf-design.md +302 -0
  100. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-04-30-breakpoint-tool-design.md +333 -0
  101. ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-05-20-sap-run-script-design.md +285 -0
  102. ktern_sapguimcp-1.0.2/domain-specific-terms.txt +84 -0
  103. ktern_sapguimcp-1.0.2/nginx-cdp-proxy.conf +26 -0
  104. ktern_sapguimcp-1.0.2/package-lock.json +29 -0
  105. ktern_sapguimcp-1.0.2/package.json +12 -0
  106. ktern_sapguimcp-1.0.2/pyproject.toml +133 -0
  107. ktern_sapguimcp-1.0.2/requirements.txt +235 -0
  108. ktern_sapguimcp-1.0.2/scripts/README.md +100 -0
  109. ktern_sapguimcp-1.0.2/scripts/add_inline_results.py +215 -0
  110. ktern_sapguimcp-1.0.2/scripts/consolidate_catalog.py +118 -0
  111. ktern_sapguimcp-1.0.2/scripts/explore_issue_717.py +292 -0
  112. ktern_sapguimcp-1.0.2/scripts/probe_dcs_full_enum.py +209 -0
  113. ktern_sapguimcp-1.0.2/scripts/probe_tree_context_menu.py +377 -0
  114. ktern_sapguimcp-1.0.2/scripts/publish-to-pypi.sh +95 -0
  115. ktern_sapguimcp-1.0.2/scripts/recapture-snapshots.ps1 +69 -0
  116. ktern_sapguimcp-1.0.2/scripts/validate_pr_629.py +457 -0
  117. ktern_sapguimcp-1.0.2/src/_sapguimcp_version.py +1 -0
  118. ktern_sapguimcp-1.0.2/src/sapguimcp/__init__.py +38 -0
  119. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/__init__.py +25 -0
  120. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/__init__.py +1733 -0
  121. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_com_thread.py +314 -0
  122. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_element_finder.py +402 -0
  123. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_key_mapping.py +43 -0
  124. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_landscape.py +49 -0
  125. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_session_registry.py +196 -0
  126. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_snapshot_render.py +86 -0
  127. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_truncation.py +55 -0
  128. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/models/__init__.py +0 -0
  129. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/models/com_results.py +64 -0
  130. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/models/script_results.py +20 -0
  131. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/types.py +12 -0
  132. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/manager.py +196 -0
  133. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/__init__.py +1 -0
  134. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/backend.py +1573 -0
  135. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/browser.py +542 -0
  136. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/chrome_finder.py +212 -0
  137. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/__init__.py +1 -0
  138. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/check_field_type.js +128 -0
  139. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/check_popup.js +162 -0
  140. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/click_table_cell.js +127 -0
  141. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/detect_form_fields.js +126 -0
  142. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/discover_buttons.js +81 -0
  143. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/discover_fields.js +152 -0
  144. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_sap_user.js +26 -0
  145. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_screen_info.js +41 -0
  146. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_screen_text.js +86 -0
  147. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_status_bar.js +155 -0
  148. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_table_data.js +264 -0
  149. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/fill_form_fields.js +112 -0
  150. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/fill_se16_filter.js +129 -0
  151. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/find_field_utils.js +226 -0
  152. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/find_main_input.js +61 -0
  153. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/find_se16_filter_input.js +168 -0
  154. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/get_dropdown_options.js +86 -0
  155. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/select_dropdown_option.js +148 -0
  156. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/set_field.js +103 -0
  157. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/set_language_field.js +19 -0
  158. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/set_okcode_field.js +16 -0
  159. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/wait_for_sap_ready.js +18 -0
  160. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js_helpers.py +18 -0
  161. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/models/__init__.py +0 -0
  162. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/models/browser_results.py +83 -0
  163. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/models/session_registry.py +260 -0
  164. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/__init__.py +23 -0
  165. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/screen_state_parser.py +129 -0
  166. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se09_parser.py +210 -0
  167. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se16_parser.py +310 -0
  168. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se24_parser.py +366 -0
  169. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se37_parser.py +299 -0
  170. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se93_parser.py +236 -0
  171. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/slg1_parser.py +296 -0
  172. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/sm30_parser.py +373 -0
  173. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/sm37_parser.py +235 -0
  174. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/spro_parser.py +182 -0
  175. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/st22_parser.py +474 -0
  176. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/types.py +12 -0
  177. ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/utils.py +61 -0
  178. ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/__init__.py +78 -0
  179. ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/loader.py +114 -0
  180. ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/models.py +518 -0
  181. ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/scraper.py +440 -0
  182. ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/search.py +218 -0
  183. ktern_sapguimcp-1.0.2/src/sapguimcp/classcatalog/__init__.py +17 -0
  184. ktern_sapguimcp-1.0.2/src/sapguimcp/classcatalog/loader.py +66 -0
  185. ktern_sapguimcp-1.0.2/src/sapguimcp/classcatalog/models.py +36 -0
  186. ktern_sapguimcp-1.0.2/src/sapguimcp/classcatalog/search.py +83 -0
  187. ktern_sapguimcp-1.0.2/src/sapguimcp/data/__init__.py +1 -0
  188. ktern_sapguimcp-1.0.2/src/sapguimcp/data/classes.json +20 -0
  189. ktern_sapguimcp-1.0.2/src/sapguimcp/data/function_modules.json +27152 -0
  190. ktern_sapguimcp-1.0.2/src/sapguimcp/data/sap_field_registry.json +98 -0
  191. ktern_sapguimcp-1.0.2/src/sapguimcp/data/sap_knowledge.md +393 -0
  192. ktern_sapguimcp-1.0.2/src/sapguimcp/data/tables.json +4311 -0
  193. ktern_sapguimcp-1.0.2/src/sapguimcp/data/transactions.json +58824 -0
  194. ktern_sapguimcp-1.0.2/src/sapguimcp/fmcatalog/__init__.py +17 -0
  195. ktern_sapguimcp-1.0.2/src/sapguimcp/fmcatalog/loader.py +66 -0
  196. ktern_sapguimcp-1.0.2/src/sapguimcp/fmcatalog/models.py +80 -0
  197. ktern_sapguimcp-1.0.2/src/sapguimcp/fmcatalog/search.py +108 -0
  198. ktern_sapguimcp-1.0.2/src/sapguimcp/lang.py +345 -0
  199. ktern_sapguimcp-1.0.2/src/sapguimcp/logging_config.py +388 -0
  200. ktern_sapguimcp-1.0.2/src/sapguimcp/loghandlers/__init__.py +5 -0
  201. ktern_sapguimcp-1.0.2/src/sapguimcp/loghandlers/feedback_issue_handler.py +247 -0
  202. ktern_sapguimcp-1.0.2/src/sapguimcp/middleware/__init__.py +5 -0
  203. ktern_sapguimcp-1.0.2/src/sapguimcp/middleware/logging.py +161 -0
  204. ktern_sapguimcp-1.0.2/src/sapguimcp/models/README.md +93 -0
  205. ktern_sapguimcp-1.0.2/src/sapguimcp/models/__init__.py +293 -0
  206. ktern_sapguimcp-1.0.2/src/sapguimcp/models/abapgit_models.py +85 -0
  207. ktern_sapguimcp-1.0.2/src/sapguimcp/models/alv_models.py +38 -0
  208. ktern_sapguimcp-1.0.2/src/sapguimcp/models/base.py +143 -0
  209. ktern_sapguimcp-1.0.2/src/sapguimcp/models/breakpoint_models.py +49 -0
  210. ktern_sapguimcp-1.0.2/src/sapguimcp/models/config.py +384 -0
  211. ktern_sapguimcp-1.0.2/src/sapguimcp/models/intent_models.py +68 -0
  212. ktern_sapguimcp-1.0.2/src/sapguimcp/models/middleware.py +139 -0
  213. ktern_sapguimcp-1.0.2/src/sapguimcp/models/quick_report_models.py +51 -0
  214. ktern_sapguimcp-1.0.2/src/sapguimcp/models/sap_results.py +480 -0
  215. ktern_sapguimcp-1.0.2/src/sapguimcp/models/screen_state.py +82 -0
  216. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se09_models.py +59 -0
  217. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se11_models.py +81 -0
  218. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se16_models.py +55 -0
  219. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se24_edit_models.py +15 -0
  220. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se24_models.py +228 -0
  221. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se37_edit_models.py +14 -0
  222. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se37_models.py +89 -0
  223. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se38_edit_models.py +15 -0
  224. ktern_sapguimcp-1.0.2/src/sapguimcp/models/se93_models.py +79 -0
  225. ktern_sapguimcp-1.0.2/src/sapguimcp/models/slg1_models.py +55 -0
  226. ktern_sapguimcp-1.0.2/src/sapguimcp/models/sm30_models.py +67 -0
  227. ktern_sapguimcp-1.0.2/src/sapguimcp/models/sm37_models.py +49 -0
  228. ktern_sapguimcp-1.0.2/src/sapguimcp/models/spro_models.py +43 -0
  229. ktern_sapguimcp-1.0.2/src/sapguimcp/models/st22_models.py +58 -0
  230. ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/README.md +63 -0
  231. ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/__init__.py +138 -0
  232. ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/abapgit_workflow.md +123 -0
  233. ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/create_business_partner.md +174 -0
  234. ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/explore_class.md +65 -0
  235. ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/explore_function_module.md +74 -0
  236. ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/explore_table.md +82 -0
  237. ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/se16_bulk_read.md +89 -0
  238. ktern_sapguimcp-1.0.2/src/sapguimcp/resources/__init__.py +6 -0
  239. ktern_sapguimcp-1.0.2/src/sapguimcp/resources/feedback_resource.py +35 -0
  240. ktern_sapguimcp-1.0.2/src/sapguimcp/resources/intent_resource.py +30 -0
  241. ktern_sapguimcp-1.0.2/src/sapguimcp/server.py +357 -0
  242. ktern_sapguimcp-1.0.2/src/sapguimcp/skills/README.md +256 -0
  243. ktern_sapguimcp-1.0.2/src/sapguimcp/skills/__init__.py +13 -0
  244. ktern_sapguimcp-1.0.2/src/sapguimcp/skills/examples/create_business_partner_bp.md +221 -0
  245. ktern_sapguimcp-1.0.2/src/sapguimcp/skills/examples/create_contract_account_caa1.md +221 -0
  246. ktern_sapguimcp-1.0.2/src/sapguimcp/skills/examples/general_navigation.md +154 -0
  247. ktern_sapguimcp-1.0.2/src/sapguimcp/skills/examples/monitor_process_documents_idxgc.md +242 -0
  248. ktern_sapguimcp-1.0.2/src/sapguimcp/tables/__init__.py +39 -0
  249. ktern_sapguimcp-1.0.2/src/sapguimcp/tables/loader.py +71 -0
  250. ktern_sapguimcp-1.0.2/src/sapguimcp/tables/models.py +47 -0
  251. ktern_sapguimcp-1.0.2/src/sapguimcp/tables/scraper.py +239 -0
  252. ktern_sapguimcp-1.0.2/src/sapguimcp/tables/search.py +114 -0
  253. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/README.md +285 -0
  254. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/__init__.py +81 -0
  255. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/abapgit_tools.py +1051 -0
  256. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/breakpoint_tools.py +945 -0
  257. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/browser_tools.py +543 -0
  258. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/catalog_tools.py +156 -0
  259. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/class_tools.py +115 -0
  260. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/com_tools.py +373 -0
  261. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/feedback_tools.py +202 -0
  262. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/field_helpers.py +209 -0
  263. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/fm_tools.py +158 -0
  264. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/intent_tools.py +81 -0
  265. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/quick_report_tools.py +429 -0
  266. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sap_list_connections_impl.py +67 -0
  267. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sap_login_impl.py +88 -0
  268. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sap_tools.py +1710 -0
  269. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/screen_state_helpers.py +177 -0
  270. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/script_tools.py +218 -0
  271. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se09_tools.py +693 -0
  272. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se11_tools.py +806 -0
  273. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se16_tools.py +1016 -0
  274. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se24_edit_tools.py +407 -0
  275. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se24_tools.py +461 -0
  276. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se37_edit_tools.py +226 -0
  277. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se37_tools.py +416 -0
  278. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se38_edit_tools.py +267 -0
  279. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se93_tools.py +325 -0
  280. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/session_tools.py +195 -0
  281. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/slg1_tools.py +398 -0
  282. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sm30_tools.py +309 -0
  283. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sm37_tools.py +573 -0
  284. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/spro_tools.py +447 -0
  285. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/st22_tools.py +646 -0
  286. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/table_helpers.py +122 -0
  287. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/table_tools.py +138 -0
  288. ktern_sapguimcp-1.0.2/src/sapguimcp/tools/tree_tools.py +256 -0
  289. ktern_sapguimcp-1.0.2/src/sapguimcp/utils.py +32 -0
  290. ktern_sapguimcp-1.0.2/tox.ini +218 -0
@@ -0,0 +1,35 @@
1
+ # SAP Web GUI URL (optional — can also be derived from systems.json host)
2
+ SAP_URL=https://your-sap-server/sap/bc/gui/sap/its/webgui
3
+
4
+ # SAP system credentials are configured in ~/.config/sap-mcp/systems.json
5
+ # (or set SAP_CONFIG_FILE to point to a different location).
6
+ # See: https://github.com/Hochfrequenz/sap-mcp-config
7
+
8
+ # Browser configuration (optional)
9
+ # Default is connect mode: expects Chrome running with --remote-debugging-port=9222
10
+ # CDP_URL=http://localhost:9222
11
+ # Uncomment to use Playwright-managed browser instead (requires `playwright install`):
12
+ # BROWSER_MODE=launch
13
+ # BROWSER_HEADLESS=false
14
+
15
+ # GitHub integration
16
+ # GITHUB_PAT is used for two things:
17
+ # 1. Feedback: creating GitHub issues via log_feedback (needs 'issues' scope on GITHUB_REPO)
18
+ # 2. abapGit: authenticating pulls from private repos (needs 'repo' scope on your ABAP repos)
19
+ # If you only set GITHUB_PAT, it is used for both.
20
+ # Generate token at: https://github.com/settings/tokens
21
+ GITHUB_USER=your-github-username
22
+ GITHUB_PAT=ghp_your_token_here
23
+ # GITHUB_REPO=Hochfrequenz/sapgui.mcp
24
+
25
+ # Optional: separate PAT for abapGit only (overrides GITHUB_PAT for pulls).
26
+ # Use this if you want different scopes for abapGit vs feedback/issues.
27
+ # ABAPGIT_PAT=ghp_your_abapgit_token_here
28
+
29
+ # Papertrail logging (optional)
30
+ # Disabled by default. Uncomment and fill in your Papertrail destination to enable:
31
+ # PAPERTRAIL_HOST=logsN.papertrailapp.com
32
+ # PAPERTRAIL_PORT=12345
33
+
34
+ # Audit logging (optional)
35
+ # AUDIT_LOG_DIR=/path/to/audit/logs
@@ -0,0 +1,16 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+
4
+ # Ensure HTML snapshots use LF line endings on all platforms
5
+ *.html text eol=lf
6
+
7
+ # Python files
8
+ *.py text eol=lf
9
+
10
+ # Config files
11
+ *.yml text eol=lf
12
+ *.yaml text eol=lf
13
+ *.toml text eol=lf
14
+ *.ini text eol=lf
15
+ *.json text eol=lf
16
+ *.md text eol=lf
@@ -0,0 +1,122 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Ad-hoc debug dumps from tool development (snapshots of live SAP screens,
7
+ # post-login DOM captures, etc.). These are written next to the server on
8
+ # demand and must never end up in the repository — they can contain system
9
+ # IDs, session tokens, and internal hostnames.
10
+ /sap_after_login*.html
11
+ /*_debug_*.yaml
12
+ /*_debug_*.html
13
+
14
+ # C extensions
15
+ *.so
16
+
17
+ # Distribution / packaging
18
+ .Python
19
+ build/
20
+ develop-eggs/
21
+ dist/
22
+ downloads/
23
+ eggs/
24
+ .eggs/
25
+ lib/
26
+ lib64/
27
+ parts/
28
+ sdist/
29
+ var/
30
+ wheels/
31
+ share/python-wheels/
32
+ *.egg-info/
33
+ .installed.cfg
34
+ *.egg
35
+ MANIFEST
36
+
37
+ # PyInstaller
38
+ *.manifest
39
+ *.spec
40
+
41
+ # Installer logs
42
+ pip-log.txt
43
+ pip-delete-this-directory.txt
44
+
45
+ # Unit test / coverage reports
46
+ htmlcov/
47
+ .tox/
48
+ .nox/
49
+ .coverage
50
+ .coverage.*
51
+ .cache
52
+ nosetests.xml
53
+ coverage.xml
54
+ *.cover
55
+ *.py,cover
56
+ .hypothesis/
57
+ .pytest_cache/
58
+ cover/
59
+
60
+ # Translations
61
+ *.mo
62
+ *.pot
63
+
64
+ # Environments
65
+ .env
66
+ # Written at build time by the build_with_remote_logging CI job to bundle
67
+ # Papertrail defaults; never commit — doing so would leak the logging
68
+ # endpoint into every build, including the public one.
69
+ /.env.production
70
+ .venv
71
+ env/
72
+ venv/
73
+ ENV/
74
+ env.bak/
75
+ venv.bak/
76
+
77
+ # mypy
78
+ .mypy_cache/
79
+ .dmypy.json
80
+ dmypy.json
81
+
82
+ # Pyre type checker
83
+ .pyre/
84
+
85
+ # pytype static type analyzer
86
+ .pytype/
87
+
88
+ # Cython debug symbols
89
+ cython_debug/
90
+
91
+ # IDE
92
+ .idea/
93
+ .vscode/
94
+ *.swp
95
+ *.swo
96
+ *~
97
+
98
+ # OS
99
+ .DS_Store
100
+ Thumbs.db
101
+
102
+ # Project specific
103
+ *.log
104
+
105
+ .claude/
106
+
107
+ src/_your_package_version.py
108
+
109
+ src/_sapguimcp_version.py
110
+
111
+ # Node.js (for prettier)
112
+ node_modules/
113
+
114
+ nul
115
+ docs/sap_gui_scripting_api_reference.pdf
116
+ docs/sap_gui_scripting_api_800/
117
+
118
+ # Git worktrees
119
+ .worktrees/
120
+
121
+ .kiro
122
+
@@ -0,0 +1,6 @@
1
+ [submodule "unittests/abapgit_repos/Z_PUBLIC_ABAPGIT_TEST_REPOSITORY"]
2
+ path = unittests/webgui/abapgit_repos/Z_PUBLIC_ABAPGIT_TEST_REPOSITORY
3
+ url = https://github.com/Hochfrequenz/Z_PUBLIC_ABAPGIT_TEST_REPOSITORY
4
+ [submodule "unittests/abapgit_repos/Z_PRIVATE_ABAPGIT_TEST_REPOSITORY"]
5
+ path = unittests/webgui/abapgit_repos/Z_PRIVATE_ABAPGIT_TEST_REPOSITORY
6
+ url = https://github.com/Hochfrequenz/Z_PRIVATE_ABAPGIT_TEST_REPOSITORY/
@@ -0,0 +1,9 @@
1
+ {
2
+ "printWidth": 100,
3
+ "tabWidth": 4,
4
+ "useTabs": false,
5
+ "semi": true,
6
+ "singleQuote": true,
7
+ "trailingComma": "es5",
8
+ "proseWrap": "preserve"
9
+ }
@@ -0,0 +1,262 @@
1
+ # Architecture
2
+
3
+ This document explains how the SAP MCP Server is structured so you can navigate the codebase, understand the request flow, and add new features without reading every file first.
4
+
5
+ ## SAP in 30 Seconds
6
+
7
+ SAP GUI is a desktop application for interacting with SAP ERP systems. Users navigate by entering **transaction codes** (tcodes like `SE16`, `VA01`, `SM37`) into the **OK-Code field** and pressing Enter. Each transaction shows a different screen with fields, tables, and buttons. The **status bar** at the bottom shows success/error messages after each action.
8
+
9
+ This MCP server automates that interaction — it enters tcodes, fills fields, reads tables, and returns structured results. It works through two backends: browser automation (WebGUI) or direct COM scripting (Desktop).
10
+
11
+ ## Layers
12
+
13
+ ```mermaid
14
+ graph TD
15
+ Client["MCP Client<br/>(Claude Desktop, Claude Code)"]
16
+ Server["FastMCP Server<br/>server.py"]
17
+ Tools["Tools Layer<br/>tools/*.py — ~27 tool modules"]
18
+ Manager["Backend Manager<br/>backend/manager.py"]
19
+ Protocol["SapUiBackend Protocol<br/>backend/protocol.py"]
20
+ WebGUI["WebGuiBackend<br/>backend/webgui/backend.py<br/>(Playwright + Chrome)"]
21
+ Desktop["DesktopBackend<br/>backend/desktop/__init__.py<br/>(COM + sapsucker)"]
22
+ Parsers["HTML Parsers<br/>backend/webgui/parsers/*.py"]
23
+ Models["Result Models<br/>models/*.py — Pydantic"]
24
+
25
+ Client -->|stdio/SSE| Server
26
+ Server --> Tools
27
+ Tools --> Manager
28
+ Manager --> Protocol
29
+ Protocol --> WebGUI
30
+ Protocol --> Desktop
31
+ WebGUI --> Parsers
32
+ Tools --> Models
33
+ WebGUI --> Models
34
+ Desktop --> Models
35
+ ```
36
+
37
+ ### Layer Responsibilities
38
+
39
+ | Layer | Key Files | What It Does |
40
+ |-------|-----------|-------------|
41
+ | **Server** | `server.py` | Creates the FastMCP app, registers all tools/resources/prompts, manages lifecycle |
42
+ | **Tools** | `tools/sap_tools.py`, `tools/se16_tools.py`, ... | Define MCP tools the LLM can call. Each tool gets a backend via `get_backend()`, calls protocol methods, returns a Pydantic result model |
43
+ | **Backend Manager** | `backend/manager.py` | Singleton that creates/caches the right backend based on `BACKEND_TYPE`. Routes session IDs to backend instances |
44
+ | **Protocol** | `backend/protocol.py` | Structural typing protocol (`SapUiBackend`) with 5 sub-protocols: Navigation, Primitives, Inspection, Editor, Popup. Both backends implement this — tools never import a concrete backend |
45
+ | **WebGUI Backend** | `backend/webgui/backend.py`, `browser.py` | Implements protocol via Playwright page automation. Fills fields with JavaScript, reads screens with ARIA snapshots |
46
+ | **Desktop Backend** | `backend/desktop/__init__.py` | Implements protocol via COM scripting through [sapsucker](https://github.com/Hochfrequenz/sapsucker). Dispatches all COM calls to a dedicated thread (`_com_thread.py`) for apartment-threading safety |
47
+ | **Parsers** | `backend/webgui/parsers/*.py` | WebGUI-specific HTML-to-structured-data extraction. One parser per transaction (e.g., `se16_parser.py`, `se24_parser.py`) |
48
+ | **Models** | `models/*.py` | Pydantic models for tool results, screen state, and config. Shared by both backends. Result models never import from backend or tools |
49
+
50
+ ## Request Flow
51
+
52
+ What happens when the LLM calls `sap_se16_query(table="MARA", max_hits=10)`:
53
+
54
+ ```mermaid
55
+ sequenceDiagram
56
+ participant LLM as MCP Client
57
+ participant Tool as se16_tools.py
58
+ participant Mgr as BackendManager
59
+ participant BE as WebGUI/Desktop Backend
60
+ participant SAP as SAP System
61
+
62
+ LLM->>Tool: sap_se16_query(table="MARA")
63
+ Tool->>Mgr: get_backend(session, agent_id)
64
+ Mgr-->>Tool: backend instance
65
+ Tool->>BE: enter_transaction("SE16N")
66
+ BE->>SAP: Navigate to SE16N
67
+ SAP-->>BE: Screen loaded
68
+ Tool->>BE: focus_and_type("Table", "MARA")
69
+ Tool->>BE: press_key("F8")
70
+ BE->>SAP: Execute query
71
+ SAP-->>BE: Results displayed
72
+ Tool->>BE: read_table(max_rows=10)
73
+ BE-->>Tool: TableData(headers, rows)
74
+ Tool-->>LLM: SE16Result(table, columns, rows)
75
+ ```
76
+
77
+ ## File Organization
78
+
79
+ Core packages only — helper packages (`catalog/`, `classcatalog/`, `fmcatalog/`, `tables/`) provide offline SAP metadata search; `middleware/`, `resources/`, `prompts/`, `workflows/`, `loghandlers/` handle cross-cutting concerns.
80
+
81
+ ```
82
+ src/sapguimcp/
83
+ server.py # FastMCP app, tool registration, lifecycle
84
+ models/
85
+ config.py # SapGuiSettings (all env vars)
86
+ base.py # ToolResult base class, TCode type, PopupInfo
87
+ sap_results.py # Shared results (LoginResult, ScreenInfo, ...)
88
+ se16_models.py # SE16-specific result models
89
+ se24_models.py # SE24-specific result models
90
+ ... # One model file per transaction
91
+ backend/
92
+ protocol.py # SapUiBackend protocol definition
93
+ manager.py # Backend factory + session routing
94
+ types.py # ScreenSnapshot, AriaSnapshot, ComTreeSnapshot aliases
95
+ webgui/
96
+ backend.py # WebGuiBackend implementation
97
+ browser.py # Chrome/Playwright lifecycle management
98
+ chrome_finder.py # Auto-detect Chrome installation
99
+ js_helpers.py # JavaScript helper loader
100
+ js/*.js # Injected JS for field filling, screen reading
101
+ parsers/ # HTML → structured data (one per transaction)
102
+ desktop/
103
+ __init__.py # DesktopBackend implementation
104
+ _com_thread.py # Dedicated COM thread (apartment-threading)
105
+ _session_registry.py # Multi-session tracking
106
+ _element_finder.py # COM tree traversal helpers
107
+ _key_mapping.py # Key name → SAP VKey mapping
108
+ _landscape.py # SAP Logon XML parsing
109
+ _discovery.py # Client/system discovery via SE16N
110
+ tools/
111
+ sap_tools.py # Core tools: login, transaction, screen, keyboard, ...
112
+ se16_tools.py # SE16N data browser (query tables)
113
+ se24_tools.py # SE24 class lookup
114
+ se24_edit_tools.py # SE24 class source editing
115
+ se37_tools.py # SE37 function module lookup
116
+ se37_edit_tools.py # SE37 function module editing
117
+ se38_edit_tools.py # SE38 report editing
118
+ ... # More transaction tools (se09, se11, se93, sm30, sm37, slg1, spro, st22)
119
+ _backend_utils.py # _is_desktop_backend() helper
120
+ field_helpers.py # Shared field-filling logic
121
+ table_helpers.py # Shared table-reading logic
122
+ session_tools.py # Multi-session management
123
+ feedback_tools.py # LLM feedback logging → GitHub issues
124
+ ```
125
+
126
+ ## How to Add a New Transaction Tool
127
+
128
+ Follow the SE16 pattern. For a new transaction `SE99`:
129
+
130
+ ### 1. Create the result model
131
+
132
+ `src/sapguimcp/models/se99_models.py`:
133
+
134
+ ```python
135
+ from pydantic import Field
136
+ from sapguimcp.models.base import ToolResult
137
+
138
+ class SE99Result(ToolResult):
139
+ """Result from sap_se99_query tool."""
140
+ data: list[dict[str, str]] = Field(default_factory=list)
141
+ # Add transaction-specific fields
142
+ ```
143
+
144
+ Export it from `models/__init__.py`.
145
+
146
+ ### 2. Create the tool file
147
+
148
+ `src/sapguimcp/tools/se99_tools.py`:
149
+
150
+ ```python
151
+ from fastmcp import FastMCP
152
+ from sapguimcp.backend.manager import get_backend
153
+ from sapguimcp.models.se99_models import SE99Result
154
+
155
+ def register_se99_tools(mcp: FastMCP) -> None:
156
+ @mcp.tool(description="Query SE99 data")
157
+ async def sap_se99_query(
158
+ param: str,
159
+ session: str | None = None,
160
+ agent_id: str | None = None,
161
+ ) -> SE99Result:
162
+ backend = await get_backend(session=session, agent_id=agent_id, tool_name="sap_se99_query")
163
+
164
+ # Navigate
165
+ tx = await backend.enter_transaction("SE99")
166
+ if not tx.success:
167
+ return SE99Result.failure(f"Navigation failed: {tx.error}")
168
+
169
+ # Fill fields, execute, read results
170
+ await backend.fill_field("Field Label", param)
171
+ await backend.press_key("F8")
172
+ # ... parse results ...
173
+
174
+ return SE99Result(data=[...])
175
+ ```
176
+
177
+ ### 3. Add desktop-specific path (if needed)
178
+
179
+ If the desktop backend needs different logic (e.g., COM table reading instead of HTML parsing), add a helper:
180
+
181
+ ```python
182
+ from sapguimcp.tools._backend_utils import _is_desktop_backend
183
+
184
+ if _is_desktop_backend(backend):
185
+ result = await _query_se99_desktop(backend, param)
186
+ else:
187
+ result = await _query_se99_webgui(backend, param)
188
+ ```
189
+
190
+ ### 4. Add a WebGUI parser (if needed)
191
+
192
+ `src/sapguimcp/backend/webgui/parsers/se99_parser.py` — for extracting structured data from HTML/ARIA snapshots. Only needed for WebGUI; desktop reads data via COM.
193
+
194
+ ### 5. Register the tool
195
+
196
+ In `server.py`, add the import and call `register_se99_tools(mcp)` alongside the existing registrations. Also export the registration function from `tools/__init__.py`.
197
+
198
+ ### 6. Add tests
199
+
200
+ - `unittests/test_se99_models.py` — model validation (offline)
201
+ - `unittests/desktop/test_se99_integration.py` — desktop integration (needs SAP, auto-skipped)
202
+ - `unittests/webgui/test_se99_integration.py` — webgui integration (needs SAP, auto-skipped)
203
+
204
+ ## Tests
205
+
206
+ ### Categories
207
+
208
+ | Category | Examples | Needs SAP? | How to run |
209
+ |----------|----------|-----------|------------|
210
+ | **Root unit tests** | `unittests/test_models.py`, `test_config.py`, `test_catalog.py`, ... | No | `tox -e unit_tests` |
211
+ | **Desktop unit tests** | `unittests/desktop/test_desktop_backend.py`, `test_com_thread.py`, `test_element_finder.py`, `test_key_mapping.py`, ... | No (mocked) | `tox -e unit_tests` |
212
+ | **Desktop integration** | `unittests/desktop/test_se16_integration.py`, `test_se24_integration.py`, ... | Yes (SAP GUI) | `tox -e integration_tests` |
213
+ | **WebGUI integration** | `unittests/webgui/test_se16_integration.py`, `test_*_exploration.py`, ... | Yes (SAP WebGUI) | `tox -e integration_tests` |
214
+
215
+ ### Skip Mechanism
216
+
217
+ Integration tests auto-skip based on **credential detection** — no hardcoded hostnames or machine lists.
218
+
219
+ - **Desktop tests** use `skip_no_sap` (defined in `unittests/desktop/conftest.py`): skips when SAP credentials are not configured in `~/.config/sap-mcp/systems.json`
220
+ - **WebGUI tests** use `has_sap_webgui_creds()` (defined in `unittests/conftest.py`): skips when SAP credentials are not configured in `~/.config/sap-mcp/systems.json` or SAP URL is missing
221
+ - Both check functions are in `unittests/conftest.py` — configure your `systems.json` file and tests run automatically
222
+
223
+ Desktop test files include `pytestmark = pytest.mark.skipif(sys.platform != "win32", reason="Windows only")` to skip on Linux/macOS CI.
224
+
225
+ ### Running Tests
226
+
227
+ ```bash
228
+ tox -e tests # Full suite (integration auto-skips without SAP)
229
+ tox -e unit_tests # All offline tests (no SAP needed)
230
+ tox -e integration_tests # SAP integration tests only
231
+ tox -e linting # pylint
232
+ tox -e type_check # mypy --strict
233
+ tox -e formatting # black + isort check
234
+ ```
235
+
236
+ ## Configuration
237
+
238
+ All settings are in `src/sapguimcp/models/config.py` and loaded from environment variables or `.env` files.
239
+
240
+ ### Core (have defaults, but needed for SAP operations)
241
+
242
+ | Variable | Description | Default |
243
+ |----------|-------------|---------|
244
+ | `BACKEND_TYPE` | `desktop` or `webgui` | `webgui` |
245
+ | `SAP_LANGUAGE` | `DE` or `EN` | `EN` |
246
+
247
+ **Desktop-only:** Connection name is configured in `~/.config/sap-mcp/systems.json`
248
+
249
+ **WebGUI-only:** `SAP_URL` — Web GUI URL (e.g., `https://server/sap/bc/gui/sap/its/webgui`)
250
+
251
+ SAP credentials (user, password, mandant) are loaded from `~/.config/sap-mcp/systems.json` (or the path set via `SAP_CONFIG_FILE`). See the [sap-mcp-config](https://github.com/Hochfrequenz/sap-mcp-config) package.
252
+
253
+ ### Optional
254
+
255
+ | Group | Variables | Purpose |
256
+ |-------|-----------|---------|
257
+ | **Browser** | `BROWSER_MODE`, `BROWSER_TYPE`, `CDP_URL`, `CHROME_PATH`, `CHROME_USER_DATA_DIR`, `BROWSER_HEADLESS` | Chrome/Playwright configuration |
258
+ | **COM timing** | `COM_MIN_INTERVAL_MS` | Minimum ms between COM calls (desktop, prevents overload) |
259
+ | **GitHub** | `GITHUB_PAT`, `GITHUB_USER`, `GITHUB_REPO`, `ABAPGIT_PAT` | Feedback issue creation, abapGit operations |
260
+ | **Logging** | `PAPERTRAIL_HOST`, `PAPERTRAIL_PORT` | Remote syslog (optional) |
261
+
262
+ See `.env.example` for a complete template with descriptions.