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.
- ktern_sapguimcp-1.0.2/.env.example +35 -0
- ktern_sapguimcp-1.0.2/.gitattributes +16 -0
- ktern_sapguimcp-1.0.2/.gitignore +122 -0
- ktern_sapguimcp-1.0.2/.gitmodules +6 -0
- ktern_sapguimcp-1.0.2/.prettierrc +9 -0
- ktern_sapguimcp-1.0.2/ARCHITECTURE.md +262 -0
- ktern_sapguimcp-1.0.2/CONTRIBUTING.md +307 -0
- ktern_sapguimcp-1.0.2/Dockerfile +50 -0
- ktern_sapguimcp-1.0.2/LICENSE +21 -0
- ktern_sapguimcp-1.0.2/PKG-INFO +777 -0
- ktern_sapguimcp-1.0.2/PUBLISHING.md +175 -0
- ktern_sapguimcp-1.0.2/README.md +717 -0
- ktern_sapguimcp-1.0.2/docker-compose.yml +27 -0
- ktern_sapguimcp-1.0.2/docs/SAP_TEST_PREREQUISITES.md +156 -0
- ktern_sapguimcp-1.0.2/docs/bulk-operations-performance.md +133 -0
- ktern_sapguimcp-1.0.2/docs/design/sap-quick-report-design.md +421 -0
- ktern_sapguimcp-1.0.2/docs/design/sap-quick-report-implementation-plan.md +1166 -0
- ktern_sapguimcp-1.0.2/docs/plans/2024-12-19-utilities-consulting-ai-tools-design.md +396 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-02-js-extraction-design.md +109 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-02-pydantic-tool-results-design.md +445 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-02-sap-fill-form-design.md +184 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-03-github-feedback-issues-design.md +109 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-03-intent-logging-design.md +204 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-04-dropdown-support-design.md +148 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-04-popup-handling-design.md +107 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-04-workflow-learning-design.md +374 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-05-popup-semantics-design.md +108 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-05-tool-capabilities-discovery-design.md +114 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-08-se11-lookup-tool-design.md +167 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-08-se16-data-browser-design.md +206 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-09-typed-test-helpers-design.md +136 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-09-typed-test-helpers.md +1124 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-12-fm-class-catalog-design.md +176 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-14-multi-session-implementation.md +1493 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-14-multi-session-support-design.md +319 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-21-agent-session-binding-design.md +152 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-21-agent-session-binding-impl.md +1177 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-23-abapgit-api-pull-design.md +231 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-01-27-mcp-prompts-design.md +85 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-13-logging-improvements-design.md +103 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-13-logging-improvements-plan.md +1002 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-13-onboarding-prompts-design.md +142 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-13-onboarding-prompts-plan.md +828 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-18-exe-bundling-design.md +174 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-18-exe-bundling-plan.md +462 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-18-sap-identity-log-correlation-design.md +95 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-18-sap-identity-log-correlation-plan.md +579 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-19-default-browser-mode-connect-design.md +26 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-19-pat-validation-design.md +95 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-19-pat-validation-plan.md +451 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-20-readme-env-vars-fix-design.md +85 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-20-readme-env-vars-fix-plan.md +429 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-20-se38-edit-tool-design.md +111 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-20-se38-edit-tool-plan.md +693 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-general-purpose-tools-design.md +422 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-se09-transport-tool-plan.md +1326 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-slg1-tool-plan.md +1330 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-sm30-tool-plan.md +1612 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-sm37-tool-plan.md +1646 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-22-st22-tool-plan.md +1786 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-24-sm30-finish-and-spro-search-plan.md +625 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-24-sm30-spro-search-design.md +112 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-26-abapgit-list-repos-design.md +63 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-02-26-abapgit-list-repos-plan.md +573 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-03-02-remove-sampling-design.md +73 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-03-02-remove-sampling-plan.md +372 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-03-03-abapgit-pull-status-bar-fix-design.md +52 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-03-03-abapgit-pull-status-bar-fix-plan.md +348 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-03-04-ui-backend-abstraction-design.md +259 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-03-04-ui-backend-abstraction-plan.md +1504 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-03-11-stateless-selection-screens-design.md +502 -0
- ktern_sapguimcp-1.0.2/docs/plans/2026-03-11-stateless-selection-screens-plan.md +1634 -0
- ktern_sapguimcp-1.0.2/docs/plans/PLAN_TRANSACTION_CATALOG.md +267 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-12-protocol-cleanup-plan.md +878 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-14-pysapgui-library.md +3895 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-15-desktop-backend-phase1.md +1285 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-16-desktop-tools-remaining.md +293 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-17-desktop-multi-session.md +279 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-18-readme-desktop-backend.md +363 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-20-pysapgui-open-source-readiness.md +1600 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-03-24-reduce-local-imports.md +395 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-04-04-popup-rework-active-window.md +886 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-04-05-full-depth-element-info.md +776 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/plans/2026-04-07-sap-fill-form-desktop-perf.md +1070 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-12-protocol-cleanup-design.md +146 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-13-backend-encapsulation-design.md +271 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-14-pysapgui-library-design.md +545 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-14-sapgui-login-fixture-design.md +204 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-15-desktop-backend-adapter-design.md +295 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-16-com-evaluate-tool-design.md +131 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-17-desktop-multi-session-design.md +126 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-18-readme-desktop-backend-design.md +106 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-20-pysapgui-open-source-readiness-design.md +186 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-24-architecture-docs-design.md +29 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-24-reduce-local-imports-design.md +124 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-03-24-test-gating-design.md +47 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-04-04-popup-rework-active-window-design.md +262 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-04-05-full-depth-element-info-design.md +206 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-04-07-sap-fill-form-desktop-perf-design.md +302 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-04-30-breakpoint-tool-design.md +333 -0
- ktern_sapguimcp-1.0.2/docs/superpowers/specs/2026-05-20-sap-run-script-design.md +285 -0
- ktern_sapguimcp-1.0.2/domain-specific-terms.txt +84 -0
- ktern_sapguimcp-1.0.2/nginx-cdp-proxy.conf +26 -0
- ktern_sapguimcp-1.0.2/package-lock.json +29 -0
- ktern_sapguimcp-1.0.2/package.json +12 -0
- ktern_sapguimcp-1.0.2/pyproject.toml +133 -0
- ktern_sapguimcp-1.0.2/requirements.txt +235 -0
- ktern_sapguimcp-1.0.2/scripts/README.md +100 -0
- ktern_sapguimcp-1.0.2/scripts/add_inline_results.py +215 -0
- ktern_sapguimcp-1.0.2/scripts/consolidate_catalog.py +118 -0
- ktern_sapguimcp-1.0.2/scripts/explore_issue_717.py +292 -0
- ktern_sapguimcp-1.0.2/scripts/probe_dcs_full_enum.py +209 -0
- ktern_sapguimcp-1.0.2/scripts/probe_tree_context_menu.py +377 -0
- ktern_sapguimcp-1.0.2/scripts/publish-to-pypi.sh +95 -0
- ktern_sapguimcp-1.0.2/scripts/recapture-snapshots.ps1 +69 -0
- ktern_sapguimcp-1.0.2/scripts/validate_pr_629.py +457 -0
- ktern_sapguimcp-1.0.2/src/_sapguimcp_version.py +1 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/__init__.py +38 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/__init__.py +25 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/__init__.py +1733 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_com_thread.py +314 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_element_finder.py +402 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_key_mapping.py +43 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_landscape.py +49 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_session_registry.py +196 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_snapshot_render.py +86 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/_truncation.py +55 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/models/__init__.py +0 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/models/com_results.py +64 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/models/script_results.py +20 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/desktop/types.py +12 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/manager.py +196 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/__init__.py +1 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/backend.py +1573 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/browser.py +542 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/chrome_finder.py +212 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/__init__.py +1 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/check_field_type.js +128 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/check_popup.js +162 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/click_table_cell.js +127 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/detect_form_fields.js +126 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/discover_buttons.js +81 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/discover_fields.js +152 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_sap_user.js +26 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_screen_info.js +41 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_screen_text.js +86 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_status_bar.js +155 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/extract_table_data.js +264 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/fill_form_fields.js +112 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/fill_se16_filter.js +129 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/find_field_utils.js +226 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/find_main_input.js +61 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/find_se16_filter_input.js +168 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/get_dropdown_options.js +86 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/select_dropdown_option.js +148 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/set_field.js +103 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/set_language_field.js +19 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/set_okcode_field.js +16 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js/wait_for_sap_ready.js +18 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/js_helpers.py +18 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/models/__init__.py +0 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/models/browser_results.py +83 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/models/session_registry.py +260 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/__init__.py +23 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/screen_state_parser.py +129 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se09_parser.py +210 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se16_parser.py +310 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se24_parser.py +366 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se37_parser.py +299 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/se93_parser.py +236 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/slg1_parser.py +296 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/sm30_parser.py +373 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/sm37_parser.py +235 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/spro_parser.py +182 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/parsers/st22_parser.py +474 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/types.py +12 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/backend/webgui/utils.py +61 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/__init__.py +78 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/loader.py +114 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/models.py +518 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/scraper.py +440 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/catalog/search.py +218 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/classcatalog/__init__.py +17 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/classcatalog/loader.py +66 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/classcatalog/models.py +36 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/classcatalog/search.py +83 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/data/__init__.py +1 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/data/classes.json +20 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/data/function_modules.json +27152 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/data/sap_field_registry.json +98 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/data/sap_knowledge.md +393 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/data/tables.json +4311 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/data/transactions.json +58824 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/fmcatalog/__init__.py +17 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/fmcatalog/loader.py +66 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/fmcatalog/models.py +80 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/fmcatalog/search.py +108 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/lang.py +345 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/logging_config.py +388 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/loghandlers/__init__.py +5 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/loghandlers/feedback_issue_handler.py +247 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/middleware/__init__.py +5 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/middleware/logging.py +161 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/README.md +93 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/__init__.py +293 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/abapgit_models.py +85 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/alv_models.py +38 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/base.py +143 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/breakpoint_models.py +49 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/config.py +384 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/intent_models.py +68 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/middleware.py +139 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/quick_report_models.py +51 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/sap_results.py +480 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/screen_state.py +82 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se09_models.py +59 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se11_models.py +81 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se16_models.py +55 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se24_edit_models.py +15 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se24_models.py +228 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se37_edit_models.py +14 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se37_models.py +89 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se38_edit_models.py +15 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/se93_models.py +79 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/slg1_models.py +55 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/sm30_models.py +67 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/sm37_models.py +49 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/spro_models.py +43 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/models/st22_models.py +58 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/README.md +63 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/__init__.py +138 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/abapgit_workflow.md +123 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/create_business_partner.md +174 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/explore_class.md +65 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/explore_function_module.md +74 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/explore_table.md +82 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/prompts/se16_bulk_read.md +89 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/resources/__init__.py +6 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/resources/feedback_resource.py +35 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/resources/intent_resource.py +30 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/server.py +357 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/skills/README.md +256 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/skills/__init__.py +13 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/skills/examples/create_business_partner_bp.md +221 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/skills/examples/create_contract_account_caa1.md +221 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/skills/examples/general_navigation.md +154 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/skills/examples/monitor_process_documents_idxgc.md +242 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tables/__init__.py +39 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tables/loader.py +71 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tables/models.py +47 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tables/scraper.py +239 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tables/search.py +114 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/README.md +285 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/__init__.py +81 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/abapgit_tools.py +1051 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/breakpoint_tools.py +945 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/browser_tools.py +543 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/catalog_tools.py +156 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/class_tools.py +115 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/com_tools.py +373 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/feedback_tools.py +202 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/field_helpers.py +209 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/fm_tools.py +158 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/intent_tools.py +81 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/quick_report_tools.py +429 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sap_list_connections_impl.py +67 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sap_login_impl.py +88 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sap_tools.py +1710 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/screen_state_helpers.py +177 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/script_tools.py +218 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se09_tools.py +693 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se11_tools.py +806 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se16_tools.py +1016 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se24_edit_tools.py +407 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se24_tools.py +461 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se37_edit_tools.py +226 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se37_tools.py +416 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se38_edit_tools.py +267 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/se93_tools.py +325 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/session_tools.py +195 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/slg1_tools.py +398 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sm30_tools.py +309 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/sm37_tools.py +573 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/spro_tools.py +447 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/st22_tools.py +646 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/table_helpers.py +122 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/table_tools.py +138 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/tools/tree_tools.py +256 -0
- ktern_sapguimcp-1.0.2/src/sapguimcp/utils.py +32 -0
- 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,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.
|