opera-cloud-mcp 0.2.0__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 (221) hide show
  1. opera_cloud_mcp-0.2.0/.claude/settings.local.json +76 -0
  2. opera_cloud_mcp-0.2.0/.coverage-ratchet.json +16 -0
  3. opera_cloud_mcp-0.2.0/.env +12 -0
  4. opera_cloud_mcp-0.2.0/.env.example +89 -0
  5. opera_cloud_mcp-0.2.0/.github/FUNDING.yml +1 -0
  6. opera_cloud_mcp-0.2.0/.gitignore +15 -0
  7. opera_cloud_mcp-0.2.0/.idea/.gitignore +8 -0
  8. opera_cloud_mcp-0.2.0/.idea/inspectionProfiles/Project_Default.xml +29 -0
  9. opera_cloud_mcp-0.2.0/.idea/inspectionProfiles/profiles_settings.xml +6 -0
  10. opera_cloud_mcp-0.2.0/.idea/misc.xml +7 -0
  11. opera_cloud_mcp-0.2.0/.idea/modules.xml +8 -0
  12. opera_cloud_mcp-0.2.0/.idea/opera-cloud-mcp.iml +10 -0
  13. opera_cloud_mcp-0.2.0/.idea/ruff.xml +6 -0
  14. opera_cloud_mcp-0.2.0/.idea/vcs.xml +6 -0
  15. opera_cloud_mcp-0.2.0/.idea/workspace.xml +208 -0
  16. opera_cloud_mcp-0.2.0/.pre-commit-config.yaml +109 -0
  17. opera_cloud_mcp-0.2.0/AGENTS.md +244 -0
  18. opera_cloud_mcp-0.2.0/CLAUDE.md +178 -0
  19. opera_cloud_mcp-0.2.0/LICENSE +29 -0
  20. opera_cloud_mcp-0.2.0/PKG-INFO +268 -0
  21. opera_cloud_mcp-0.2.0/QWEN.md +166 -0
  22. opera_cloud_mcp-0.2.0/README.md +252 -0
  23. opera_cloud_mcp-0.2.0/coverage.json +1 -0
  24. opera_cloud_mcp-0.2.0/docs/README.md +45 -0
  25. opera_cloud_mcp-0.2.0/docs/base-client-implementation.md +290 -0
  26. opera_cloud_mcp-0.2.0/docs/implementation-plan.md +746 -0
  27. opera_cloud_mcp-0.2.0/docs/phase5-summary.md +154 -0
  28. opera_cloud_mcp-0.2.0/docs/production-monitoring.md +353 -0
  29. opera_cloud_mcp-0.2.0/docs/security-implementation.md +485 -0
  30. opera_cloud_mcp-0.2.0/example.mcp.dev.json +35 -0
  31. opera_cloud_mcp-0.2.0/example.mcp.json +27 -0
  32. opera_cloud_mcp-0.2.0/examples/auth_example.py +130 -0
  33. opera_cloud_mcp-0.2.0/examples/base_client_usage.py +250 -0
  34. opera_cloud_mcp-0.2.0/htmlcov/.gitignore +2 -0
  35. opera_cloud_mcp-0.2.0/htmlcov/class_index.html +2075 -0
  36. opera_cloud_mcp-0.2.0/htmlcov/config_test_py.html +131 -0
  37. opera_cloud_mcp-0.2.0/htmlcov/coverage_html_cb_6fb7b396.js +733 -0
  38. opera_cloud_mcp-0.2.0/htmlcov/debug_ast_py.html +125 -0
  39. opera_cloud_mcp-0.2.0/htmlcov/debug_confirmation2_py.html +133 -0
  40. opera_cloud_mcp-0.2.0/htmlcov/debug_confirmation_py.html +124 -0
  41. opera_cloud_mcp-0.2.0/htmlcov/debug_errors_py.html +113 -0
  42. opera_cloud_mcp-0.2.0/htmlcov/debug_gender_py.html +133 -0
  43. opera_cloud_mcp-0.2.0/htmlcov/debug_guest2_py.html +168 -0
  44. opera_cloud_mcp-0.2.0/htmlcov/debug_guest_py.html +158 -0
  45. opera_cloud_mcp-0.2.0/htmlcov/debug_model_py.html +132 -0
  46. opera_cloud_mcp-0.2.0/htmlcov/favicon_32_cb_58284776.png +0 -0
  47. opera_cloud_mcp-0.2.0/htmlcov/function_index.html +7723 -0
  48. opera_cloud_mcp-0.2.0/htmlcov/index.html +482 -0
  49. opera_cloud_mcp-0.2.0/htmlcov/keybd_closed_cb_ce680311.png +0 -0
  50. opera_cloud_mcp-0.2.0/htmlcov/main_py.html +541 -0
  51. opera_cloud_mcp-0.2.0/htmlcov/minimal_test_py.html +113 -0
  52. opera_cloud_mcp-0.2.0/htmlcov/status.json +1 -0
  53. opera_cloud_mcp-0.2.0/htmlcov/style_cb_6b508a39.css +377 -0
  54. opera_cloud_mcp-0.2.0/htmlcov/test_regex_ok_py.html +117 -0
  55. opera_cloud_mcp-0.2.0/htmlcov/z_0113592e8142c3fd_bccache_py.html +200 -0
  56. opera_cloud_mcp-0.2.0/htmlcov/z_0113592e8142c3fd_compiler_py.html +124 -0
  57. opera_cloud_mcp-0.2.0/htmlcov/z_0113592e8142c3fd_environment_py.html +509 -0
  58. opera_cloud_mcp-0.2.0/htmlcov/z_37279972ca6c983f___init___py.html +478 -0
  59. opera_cloud_mcp-0.2.0/htmlcov/z_37279972ca6c983f_audit_logger_py.html +906 -0
  60. opera_cloud_mcp-0.2.0/htmlcov/z_37279972ca6c983f_audit_sqlmodel_py.html +237 -0
  61. opera_cloud_mcp-0.2.0/htmlcov/z_37279972ca6c983f_oauth_handler_py.html +728 -0
  62. opera_cloud_mcp-0.2.0/htmlcov/z_37279972ca6c983f_secure_oauth_handler_py.html +964 -0
  63. opera_cloud_mcp-0.2.0/htmlcov/z_37279972ca6c983f_security_enhancements_py.html +598 -0
  64. opera_cloud_mcp-0.2.0/htmlcov/z_37279972ca6c983f_security_middleware_py.html +938 -0
  65. opera_cloud_mcp-0.2.0/htmlcov/z_37fddd2ff037de4f___init___py.html +105 -0
  66. opera_cloud_mcp-0.2.0/htmlcov/z_37fddd2ff037de4f_common_py.html +191 -0
  67. opera_cloud_mcp-0.2.0/htmlcov/z_37fddd2ff037de4f_financial_py.html +145 -0
  68. opera_cloud_mcp-0.2.0/htmlcov/z_37fddd2ff037de4f_guest_py.html +552 -0
  69. opera_cloud_mcp-0.2.0/htmlcov/z_37fddd2ff037de4f_reservation_py.html +466 -0
  70. opera_cloud_mcp-0.2.0/htmlcov/z_37fddd2ff037de4f_room_py.html +145 -0
  71. opera_cloud_mcp-0.2.0/htmlcov/z_3d12e34214919cf8_manager_py.html +607 -0
  72. opera_cloud_mcp-0.2.0/htmlcov/z_3d12e34214919cf8_strategies_py.html +601 -0
  73. opera_cloud_mcp-0.2.0/htmlcov/z_3d12e34214919cf8_typed_py.html +366 -0
  74. opera_cloud_mcp-0.2.0/htmlcov/z_3d12e34214919cf8_unified_py.html +291 -0
  75. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de___init___py.html +119 -0
  76. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de_cache_manager_py.html +749 -0
  77. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de_client_factory_py.html +293 -0
  78. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de_connection_optimizer_py.html +557 -0
  79. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de_exceptions_py.html +653 -0
  80. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de_formatters_py.html +314 -0
  81. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de_observability_py.html +997 -0
  82. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de_resilience_manager_py.html +851 -0
  83. opera_cloud_mcp-0.2.0/htmlcov/z_4883c40a61b180de_validators_py.html +355 -0
  84. opera_cloud_mcp-0.2.0/htmlcov/z_58ef8218edfcd01a___init___py.html +117 -0
  85. opera_cloud_mcp-0.2.0/htmlcov/z_58ef8218edfcd01a___main___py.html +109 -0
  86. opera_cloud_mcp-0.2.0/htmlcov/z_58ef8218edfcd01a_cli_py.html +320 -0
  87. opera_cloud_mcp-0.2.0/htmlcov/z_58ef8218edfcd01a_main_py.html +493 -0
  88. opera_cloud_mcp-0.2.0/htmlcov/z_58ef8218edfcd01a_server_py.html +132 -0
  89. opera_cloud_mcp-0.2.0/htmlcov/z_692e39b0e5d2a0b5___init___py.html +109 -0
  90. opera_cloud_mcp-0.2.0/htmlcov/z_692e39b0e5d2a0b5_base_client_py.html +1864 -0
  91. opera_cloud_mcp-0.2.0/htmlcov/z_692e39b0e5d2a0b5_base_client_refactored_py.html +1495 -0
  92. opera_cloud_mcp-0.2.0/htmlcov/z_692e39b0e5d2a0b5_client_factory_py.html +505 -0
  93. opera_cloud_mcp-0.2.0/htmlcov/z_6ae3826fa9550496___init___py.html +103 -0
  94. opera_cloud_mcp-0.2.0/htmlcov/z_6ae3826fa9550496_financial_tools_py.html +882 -0
  95. opera_cloud_mcp-0.2.0/htmlcov/z_6ae3826fa9550496_guest_tools_py.html +915 -0
  96. opera_cloud_mcp-0.2.0/htmlcov/z_6ae3826fa9550496_operation_tools_py.html +1001 -0
  97. opera_cloud_mcp-0.2.0/htmlcov/z_6ae3826fa9550496_reservation_tools_py.html +799 -0
  98. opera_cloud_mcp-0.2.0/htmlcov/z_6ae3826fa9550496_room_tools_py.html +899 -0
  99. opera_cloud_mcp-0.2.0/htmlcov/z_6ae3826fa9550496_tool_registry_py.html +738 -0
  100. opera_cloud_mcp-0.2.0/htmlcov/z_6d0b68619f7d2a2f_context_py.html +161 -0
  101. opera_cloud_mcp-0.2.0/htmlcov/z_6d0b68619f7d2a2f_fixtures_py.html +173 -0
  102. opera_cloud_mcp-0.2.0/htmlcov/z_9352086f367182b9_cache_py.html +131 -0
  103. opera_cloud_mcp-0.2.0/htmlcov/z_9352086f367182b9_codegen_py.html +1054 -0
  104. opera_cloud_mcp-0.2.0/htmlcov/z_9352086f367182b9_dependencies_py.html +156 -0
  105. opera_cloud_mcp-0.2.0/htmlcov/z_9352086f367182b9_frame_py.html +194 -0
  106. opera_cloud_mcp-0.2.0/htmlcov/z_9352086f367182b9_loops_py.html +157 -0
  107. opera_cloud_mcp-0.2.0/htmlcov/z_9352086f367182b9_patterns_py.html +217 -0
  108. opera_cloud_mcp-0.2.0/htmlcov/z_a15f9f4d1acec077___init___py.html +109 -0
  109. opera_cloud_mcp-0.2.0/htmlcov/z_a15f9f4d1acec077_security_settings_py.html +533 -0
  110. opera_cloud_mcp-0.2.0/htmlcov/z_a15f9f4d1acec077_settings_py.html +328 -0
  111. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057___init___py.html +105 -0
  112. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_activities_py.html +953 -0
  113. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_block_py.html +712 -0
  114. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_cashiering_py.html +887 -0
  115. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_crm_py.html +1036 -0
  116. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_front_office_py.html +611 -0
  117. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_housekeeping_py.html +689 -0
  118. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_inventory_py.html +886 -0
  119. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_rates_py.html +828 -0
  120. opera_cloud_mcp-0.2.0/htmlcov/z_b6c5a45813e26057_reservations_py.html +1025 -0
  121. opera_cloud_mcp-0.2.0/htmlcov/z_bc5530ecc82d25cf___init___py.html +109 -0
  122. opera_cloud_mcp-0.2.0/htmlcov/z_bc5530ecc82d25cf_api_specs_py.html +666 -0
  123. opera_cloud_mcp-0.2.0/htmlcov/z_bc5530ecc82d25cf_health_check_py.html +286 -0
  124. opera_cloud_mcp-0.2.0/htmlcov/z_c396a7560d6a1190_base_py.html +587 -0
  125. opera_cloud_mcp-0.2.0/htmlcov/z_c396a7560d6a1190_choice_py.html +245 -0
  126. opera_cloud_mcp-0.2.0/htmlcov/z_c396a7560d6a1190_dict_py.html +239 -0
  127. opera_cloud_mcp-0.2.0/htmlcov/z_c396a7560d6a1190_filesystem_py.html +381 -0
  128. opera_cloud_mcp-0.2.0/htmlcov/z_c396a7560d6a1190_function_py.html +343 -0
  129. opera_cloud_mcp-0.2.0/htmlcov/z_c396a7560d6a1190_package_py.html +578 -0
  130. opera_cloud_mcp-0.2.0/monitoring/alert_rules.yml +140 -0
  131. opera_cloud_mcp-0.2.0/monitoring/prometheus.yml +63 -0
  132. opera_cloud_mcp-0.2.0/mypy.ini +18 -0
  133. opera_cloud_mcp-0.2.0/opera_cloud_mcp/__init__.py +20 -0
  134. opera_cloud_mcp-0.2.0/opera_cloud_mcp/__main__.py +12 -0
  135. opera_cloud_mcp-0.2.0/opera_cloud_mcp/auth/__init__.py +381 -0
  136. opera_cloud_mcp-0.2.0/opera_cloud_mcp/auth/audit_logger.py +809 -0
  137. opera_cloud_mcp-0.2.0/opera_cloud_mcp/auth/audit_sqlmodel.py +140 -0
  138. opera_cloud_mcp-0.2.0/opera_cloud_mcp/auth/oauth_handler.py +631 -0
  139. opera_cloud_mcp-0.2.0/opera_cloud_mcp/auth/secure_oauth_handler.py +867 -0
  140. opera_cloud_mcp-0.2.0/opera_cloud_mcp/auth/security_enhancements.py +501 -0
  141. opera_cloud_mcp-0.2.0/opera_cloud_mcp/auth/security_middleware.py +841 -0
  142. opera_cloud_mcp-0.2.0/opera_cloud_mcp/cli.py +223 -0
  143. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/__init__.py +12 -0
  144. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/__init__.py +8 -0
  145. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/activities.py +856 -0
  146. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/block.py +615 -0
  147. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/cashiering.py +790 -0
  148. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/crm.py +939 -0
  149. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/front_office.py +514 -0
  150. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/housekeeping.py +592 -0
  151. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/inventory.py +789 -0
  152. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/rates.py +731 -0
  153. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/api_clients/reservations.py +928 -0
  154. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/base_client.py +1767 -0
  155. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/base_client_refactored.py +1398 -0
  156. opera_cloud_mcp-0.2.0/opera_cloud_mcp/clients/client_factory.py +408 -0
  157. opera_cloud_mcp-0.2.0/opera_cloud_mcp/config/__init__.py +12 -0
  158. opera_cloud_mcp-0.2.0/opera_cloud_mcp/config/security_settings.py +436 -0
  159. opera_cloud_mcp-0.2.0/opera_cloud_mcp/config/settings.py +231 -0
  160. opera_cloud_mcp-0.2.0/opera_cloud_mcp/main.py +396 -0
  161. opera_cloud_mcp-0.2.0/opera_cloud_mcp/models/__init__.py +8 -0
  162. opera_cloud_mcp-0.2.0/opera_cloud_mcp/models/common.py +94 -0
  163. opera_cloud_mcp-0.2.0/opera_cloud_mcp/models/financial.py +48 -0
  164. opera_cloud_mcp-0.2.0/opera_cloud_mcp/models/guest.py +455 -0
  165. opera_cloud_mcp-0.2.0/opera_cloud_mcp/models/reservation.py +369 -0
  166. opera_cloud_mcp-0.2.0/opera_cloud_mcp/models/room.py +48 -0
  167. opera_cloud_mcp-0.2.0/opera_cloud_mcp/resources/__init__.py +12 -0
  168. opera_cloud_mcp-0.2.0/opera_cloud_mcp/resources/api_specs.py +569 -0
  169. opera_cloud_mcp-0.2.0/opera_cloud_mcp/resources/health_check.py +189 -0
  170. opera_cloud_mcp-0.2.0/opera_cloud_mcp/server.py +35 -0
  171. opera_cloud_mcp-0.2.0/opera_cloud_mcp/tools/__init__.py +6 -0
  172. opera_cloud_mcp-0.2.0/opera_cloud_mcp/tools/financial_tools.py +785 -0
  173. opera_cloud_mcp-0.2.0/opera_cloud_mcp/tools/guest_tools.py +818 -0
  174. opera_cloud_mcp-0.2.0/opera_cloud_mcp/tools/operation_tools.py +904 -0
  175. opera_cloud_mcp-0.2.0/opera_cloud_mcp/tools/reservation_tools.py +702 -0
  176. opera_cloud_mcp-0.2.0/opera_cloud_mcp/tools/room_tools.py +802 -0
  177. opera_cloud_mcp-0.2.0/opera_cloud_mcp/tools/tool_registry.py +641 -0
  178. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/__init__.py +22 -0
  179. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/cache_manager.py +652 -0
  180. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/client_factory.py +196 -0
  181. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/connection_optimizer.py +460 -0
  182. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/exceptions.py +556 -0
  183. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/formatters.py +217 -0
  184. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/observability.py +900 -0
  185. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/resilience_manager.py +754 -0
  186. opera_cloud_mcp-0.2.0/opera_cloud_mcp/utils/validators.py +258 -0
  187. opera_cloud_mcp-0.2.0/pyproject.toml +181 -0
  188. opera_cloud_mcp-0.2.0/refactoring_plan.md +76 -0
  189. opera_cloud_mcp-0.2.0/refactoring_summary.md +116 -0
  190. opera_cloud_mcp-0.2.0/requirements.txt +186 -0
  191. opera_cloud_mcp-0.2.0/tests/__init__.py +6 -0
  192. opera_cloud_mcp-0.2.0/tests/conftest.py +49 -0
  193. opera_cloud_mcp-0.2.0/tests/fixtures/__init__.py +1 -0
  194. opera_cloud_mcp-0.2.0/tests/fixtures/mock_responses.py +239 -0
  195. opera_cloud_mcp-0.2.0/tests/integration/__init__.py +1 -0
  196. opera_cloud_mcp-0.2.0/tests/integration/test_main_integration.py +266 -0
  197. opera_cloud_mcp-0.2.0/tests/integration/test_reservation_integration.py +476 -0
  198. opera_cloud_mcp-0.2.0/tests/integration/test_tools.py +46 -0
  199. opera_cloud_mcp-0.2.0/tests/integration/test_workflows.py +36 -0
  200. opera_cloud_mcp-0.2.0/tests/performance/__init__.py +3 -0
  201. opera_cloud_mcp-0.2.0/tests/performance/load_test.py +315 -0
  202. opera_cloud_mcp-0.2.0/tests/performance/test_performance.py +314 -0
  203. opera_cloud_mcp-0.2.0/tests/test_oauth_integration.py +412 -0
  204. opera_cloud_mcp-0.2.0/tests/unit/__init__.py +1 -0
  205. opera_cloud_mcp-0.2.0/tests/unit/test_activities_client.py +318 -0
  206. opera_cloud_mcp-0.2.0/tests/unit/test_api_specs.py +374 -0
  207. opera_cloud_mcp-0.2.0/tests/unit/test_auth.py +157 -0
  208. opera_cloud_mcp-0.2.0/tests/unit/test_clients.py +253 -0
  209. opera_cloud_mcp-0.2.0/tests/unit/test_crm_client.py +802 -0
  210. opera_cloud_mcp-0.2.0/tests/unit/test_enhanced_oauth_integration.py +252 -0
  211. opera_cloud_mcp-0.2.0/tests/unit/test_financial_tools.py +79 -0
  212. opera_cloud_mcp-0.2.0/tests/unit/test_front_office_client.py +936 -0
  213. opera_cloud_mcp-0.2.0/tests/unit/test_guest_tools.py +157 -0
  214. opera_cloud_mcp-0.2.0/tests/unit/test_models.py +326 -0
  215. opera_cloud_mcp-0.2.0/tests/unit/test_operation_tools.py +82 -0
  216. opera_cloud_mcp-0.2.0/tests/unit/test_reservation_models.py +554 -0
  217. opera_cloud_mcp-0.2.0/tests/unit/test_reservation_tools.py +361 -0
  218. opera_cloud_mcp-0.2.0/tests/unit/test_reservation_tools_simple.py +96 -0
  219. opera_cloud_mcp-0.2.0/tests/unit/test_reservations_client.py +535 -0
  220. opera_cloud_mcp-0.2.0/tests/unit/test_room_tools.py +194 -0
  221. opera_cloud_mcp-0.2.0/uv.lock +3290 -0
@@ -0,0 +1,76 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "mcp__crackerjack__init_crackerjack",
5
+ "Bash(uv sync:*)",
6
+ "Bash(uv run pre-commit:*)",
7
+ "WebFetch(domain:www.oracle.com)",
8
+ "Bash(curl:*)",
9
+ "Bash(python:*)",
10
+ "mcp__session-mgmt__init",
11
+ "mcp__filesystem__directory_tree",
12
+ "mcp__filesystem__list_directory",
13
+ "Bash(uv run:*)",
14
+ "mcp__filesystem__read_file",
15
+ "mcp__filesystem__edit_file",
16
+ "mcp__filesystem__write_file",
17
+ "Bash(grep:*)",
18
+ "mcp__crackerjack__execute_crackerjack",
19
+ "mcp__session-mgmt__checkpoint",
20
+ "mcp__session-mgmt__end",
21
+ "Bash(find:*)",
22
+ "mcp__filesystem__create_directory",
23
+ "mcp__filesystem__search_files",
24
+ "Bash(uv list:*)",
25
+ "Bash(uv pip:*)",
26
+ "Read(/Users/les/Projects/crackerjack/**)",
27
+ "mcp__filesystem__move_file",
28
+ "Read(/Users/les/Projects/session-mgmt-mcp/session_mgmt_mcp/**)",
29
+ "Read(/Users/les/Projects/session-mgmt-mcp/session_mgmt_mcp/**)",
30
+ "Read(/Users/les/Projects/session-mgmt-mcp/session_mgmt_mcp/**)",
31
+ "mcp__gitlab__create_repository",
32
+ "Bash(git remote add:*)",
33
+ "Bash(git branch:*)",
34
+ "Bash(git push:*)",
35
+ "Bash(git add:*)",
36
+ "Bash(git commit:*)",
37
+ "mcp__github__create_repository",
38
+ "mcp__github__search_repositories",
39
+ "Read(//Users/les/**)",
40
+ "Bash(timeout 5 uv run:*)",
41
+ "Bash(timeout 3 uv run:*)",
42
+ "Bash(uvx session-mgmt checkpoint:*)",
43
+ "Bash(npx:*)",
44
+ "Bash(git reset:*)",
45
+ "mcp__session-mgmt__crackerjack_run",
46
+ "Bash(timeout 30 uv run pytest tests/unit/ --maxfail=5 -x)",
47
+ "Bash(RUST_BACKTRACE=1 uv run zuban check .)",
48
+ "Bash(env RUST_BACKTRACE=1 uv run zuban check .)",
49
+ "Bash(timeout 30 uv run pytest tests/unit/ --maxfail=3 -x)",
50
+ "Bash(timeout:*)",
51
+ "Bash(git checkout:*)",
52
+ "Bash(uv add:*)",
53
+ "mcp__sequential-thinking__sequentialthinking"
54
+ ]
55
+ },
56
+ "enableAllProjectMcpServers": true,
57
+ "enabledMcpjsonServers": [
58
+ "session-mgmt",
59
+ "crackerjack",
60
+ "ast-grep",
61
+ "macos_automator",
62
+ "peekaboo",
63
+ "playwright",
64
+ "git",
65
+ "github",
66
+ "gitlab",
67
+ "memory",
68
+ "sequential-thinking",
69
+ "filesystem",
70
+ "jetbrains",
71
+ "gemini-cli",
72
+ "context7",
73
+ "raindrop",
74
+ "excalidraw"
75
+ ]
76
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "baseline": 37.016499864755204,
3
+ "current_minimum": 37.016499864755204,
4
+ "target": 100.0,
5
+ "last_updated": "2025-09-18T18:43:36.534645",
6
+ "history": [
7
+ {
8
+ "date": "2025-09-18T18:43:36.534675",
9
+ "coverage": 37.016499864755204,
10
+ "commit": "baseline",
11
+ "milestone": false
12
+ }
13
+ ],
14
+ "milestones_achieved": [],
15
+ "next_milestone": 40
16
+ }
@@ -0,0 +1,12 @@
1
+ # Minimal configuration for testing
2
+ OPERA_CLIENT_ID=test_client_id
3
+ OPERA_CLIENT_SECRET=test_client_secret
4
+ OPERA_TOKEN_URL=https://api.oracle-hospitality.com/oauth/v1/tokens
5
+ OPERA_BASE_URL=https://api.oracle-hospitality.com
6
+ OPERA_API_VERSION=v1
7
+ OPERA_ENVIRONMENT=development
8
+ OPERA_DEFAULT_HOTEL_ID=TEST_HOTEL
9
+ OPERA_REQUEST_TIMEOUT=30
10
+ OPERA_MAX_RETRIES=3
11
+ OPERA_ENABLE_CACHE=false
12
+ OPERA_LOG_LEVEL=INFO
@@ -0,0 +1,89 @@
1
+ # OPERA Cloud MCP Server Configuration
2
+ # Copy this file to .env and fill in your actual values
3
+
4
+ # Required: OAuth2 Credentials
5
+ OPERA_CLIENT_ID=your_opera_client_id_here
6
+ OPERA_CLIENT_SECRET=your_opera_client_secret_here
7
+
8
+ # Required: API Configuration
9
+ OPERA_TOKEN_URL=https://api.oracle-hospitality.com/oauth/v1/tokens
10
+ OPERA_BASE_URL=https://api.oracle-hospitality.com
11
+ OPERA_API_VERSION=v1
12
+
13
+ # Environment (production, staging, development)
14
+ OPERA_ENVIRONMENT=production
15
+
16
+ # Optional: Default Hotel Configuration
17
+ OPERA_DEFAULT_HOTEL_ID=your_hotel_id_here
18
+
19
+ # Optional: HTTP Client Configuration
20
+ OPERA_REQUEST_TIMEOUT=30
21
+ OPERA_MAX_RETRIES=3
22
+
23
+ # Optional: OAuth Configuration
24
+ OPERA_OAUTH_MAX_RETRIES=3
25
+ OPERA_OAUTH_RETRY_BACKOFF=1.0
26
+
27
+ # Optional: Caching Configuration
28
+ OPERA_ENABLE_CACHE=true
29
+ OPERA_CACHE_TTL=300
30
+ OPERA_ENABLE_PERSISTENT_TOKEN_CACHE=true
31
+ # OPERA_TOKEN_CACHE_DIR=/custom/cache/directory
32
+
33
+ # Optional: Logging Configuration
34
+ OPERA_LOG_LEVEL=INFO
35
+ OPERA_LOG_FORMAT=%(asctime)s - %(name)s - %(levelname)s - %(message)s
36
+ OPERA_ENABLE_STRUCTURED_LOGGING=true
37
+
38
+ # =============================================================================
39
+ # PRODUCTION SECURITY CONFIGURATION
40
+ # =============================================================================
41
+ # Copy and uncomment these settings for production deployment
42
+
43
+ # Core Security Features
44
+ # OPERA_SECURITY_ENABLE_SECURITY_MONITORING=true
45
+ # OPERA_SECURITY_ENABLE_AUDIT_LOGGING=true
46
+ # OPERA_SECURITY_ENABLE_RATE_LIMITING=true
47
+ # OPERA_SECURITY_ENABLE_TOKEN_BINDING=true
48
+
49
+ # Rate Limiting Configuration
50
+ # OPERA_SECURITY_AUTH_RATE_LIMIT_REQUESTS=10
51
+ # OPERA_SECURITY_AUTH_RATE_LIMIT_WINDOW_MINUTES=5
52
+
53
+ # Authentication Security
54
+ # OPERA_SECURITY_MAX_FAILED_ATTEMPTS=5
55
+ # OPERA_SECURITY_CLIENT_LOCKOUT_DURATION_MINUTES=15
56
+ # OPERA_SECURITY_TOKEN_MAX_LIFETIME_HOURS=24
57
+ # OPERA_SECURITY_TOKEN_REFRESH_THRESHOLD_MINUTES=5
58
+
59
+ # Network Security
60
+ # OPERA_SECURITY_ALLOWED_IP_ADDRESSES=192.168.1.0/24,10.0.0.0/8
61
+ # OPERA_SECURITY_REQUIRE_HTTPS=true
62
+ # OPERA_SECURITY_MIN_TLS_VERSION=1.2
63
+
64
+ # Audit and Monitoring
65
+ # OPERA_SECURITY_SECURITY_EVENT_RETENTION_DAYS=90
66
+ # OPERA_SECURITY_AUDIT_DB_ENCRYPTION_KEY=your_base64_encoded_32_byte_key_here
67
+ # OPERA_SECURITY_ENABLE_ANOMALY_DETECTION=true
68
+ # OPERA_SECURITY_ANOMALY_DETECTION_SENSITIVITY=0.7
69
+
70
+ # Incident Response
71
+ # OPERA_SECURITY_ENABLE_AUTOMATIC_INCIDENT_RESPONSE=true
72
+ # OPERA_SECURITY_SECURITY_NOTIFICATION_WEBHOOK=https://your-webhook-url.com/security-alerts
73
+ # OPERA_SECURITY_SECURITY_NOTIFICATION_EMAIL=security@yourcompany.com
74
+
75
+ # Compliance and Privacy
76
+ # OPERA_SECURITY_ENABLE_GDPR_MODE=false
77
+ # OPERA_SECURITY_DATA_RETENTION_POLICY_DAYS=365
78
+ # OPERA_SECURITY_ENABLE_PII_ANONYMIZATION=true
79
+
80
+ # Security Headers
81
+ # OPERA_SECURITY_ENABLE_SECURITY_HEADERS=true
82
+ # OPERA_SECURITY_CONTENT_SECURITY_POLICY="default-src 'self'; script-src 'self' 'unsafe-inline'"
83
+
84
+ # Development/Testing (DISABLE IN PRODUCTION)
85
+ # OPERA_SECURITY_SECURITY_TESTING_MODE=false
86
+ # OPERA_SECURITY_ENABLE_SECURITY_DEBUG_LOGS=false
87
+
88
+ # Advanced Threat Detection
89
+ # OPERA_SECURITY_ENABLE_IP_REPUTATION_CHECK=false
@@ -0,0 +1 @@
1
+ github: [lesleslie]
@@ -0,0 +1,15 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ /.envrc
12
+ /.mcp.json
13
+ /.python-version
14
+ /.coverage
15
+ /.crackerjack/
@@ -0,0 +1,8 @@
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Datasource local storage ignored files
7
+ /dataSources/
8
+ /dataSources.local.xml
@@ -0,0 +1,29 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
+ <inspection_tool class="JSHint" enabled="true" level="ERROR" enabled_by_default="true" />
6
+ <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
7
+ <option name="ignoredErrors">
8
+ <list>
9
+ <option value="N802" />
10
+ </list>
11
+ </option>
12
+ </inspection_tool>
13
+ <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
14
+ <option name="ignoredIdentifiers">
15
+ <list>
16
+ <option value="google.cloud.storage" />
17
+ <option value="firebase.ic" />
18
+ <option value="templates.ic" />
19
+ <option value="cloud_storage.ic" />
20
+ <option value="memorystore.ic" />
21
+ <option value="main.ic" />
22
+ <option value="models.ic" />
23
+ <option value="sys._getframe" />
24
+ </list>
25
+ </option>
26
+ </inspection_tool>
27
+ <inspection_tool class="PyprojectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
28
+ </profile>
29
+ </component>
@@ -0,0 +1,6 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Black">
4
+ <option name="sdkName" value="Python 3.12 (opera-cloud-mcp)" />
5
+ </component>
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="uv (opera-cloud-mcp)" project-jdk-type="Python SDK" />
7
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/opera-cloud-mcp.iml" filepath="$PROJECT_DIR$/.idea/opera-cloud-mcp.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/.venv" />
6
+ </content>
7
+ <orderEntry type="jdk" jdkName="uv (opera-cloud-mcp)" jdkType="Python SDK" />
8
+ <orderEntry type="sourceFolder" forTests="false" />
9
+ </component>
10
+ </module>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="RuffConfigService">
4
+ <option name="globalRuffExecutablePath" value="/usr/local/bin/ruff" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,208 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AutoImportSettings">
4
+ <option name="autoReloadType" value="SELECTIVE" />
5
+ </component>
6
+ <component name="ChangeListManager">
7
+ <list default="true" id="af953397-b617-4550-a2f9-24aa65c57a56" name="Changes" comment="">
8
+ <change afterPath="$PROJECT_DIR$/.coverage-ratchet.json" afterDir="false" />
9
+ <change afterPath="$PROJECT_DIR$/.env" afterDir="false" />
10
+ <change afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" afterDir="false" />
11
+ <change afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" afterDir="false" />
12
+ <change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
13
+ <change afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
14
+ <change afterPath="$PROJECT_DIR$/.idea/opera-cloud-mcp.iml" afterDir="false" />
15
+ <change afterPath="$PROJECT_DIR$/.idea/ruff.xml" afterDir="false" />
16
+ <change afterPath="$PROJECT_DIR$/LICENSE" afterDir="false" />
17
+ <change afterPath="$PROJECT_DIR$/QWEN.md" afterDir="false" />
18
+ <change afterPath="$PROJECT_DIR$/coverage.json" afterDir="false" />
19
+ <change afterPath="$PROJECT_DIR$/mypy.ini" afterDir="false" />
20
+ <change afterPath="$PROJECT_DIR$/opera_cloud_mcp/auth/audit_sqlmodel.py" afterDir="false" />
21
+ <change afterPath="$PROJECT_DIR$/opera_cloud_mcp/cli.py" afterDir="false" />
22
+ <change beforePath="$PROJECT_DIR$/.dockerignore" beforeDir="false" />
23
+ <change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
24
+ <change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
25
+ <change beforePath="$PROJECT_DIR$/.pre-commit-config.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/.pre-commit-config.yaml" afterDir="false" />
26
+ <change beforePath="$PROJECT_DIR$/CLAUDE.md" beforeDir="false" afterPath="$PROJECT_DIR$/CLAUDE.md" afterDir="false" />
27
+ <change beforePath="$PROJECT_DIR$/Dockerfile" beforeDir="false" />
28
+ <change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
29
+ <change beforePath="$PROJECT_DIR$/docker-compose.yml" beforeDir="false" />
30
+ <change beforePath="$PROJECT_DIR$/examples/auth_example.py" beforeDir="false" afterPath="$PROJECT_DIR$/examples/auth_example.py" afterDir="false" />
31
+ <change beforePath="$PROJECT_DIR$/examples/base_client_usage.py" beforeDir="false" afterPath="$PROJECT_DIR$/examples/base_client_usage.py" afterDir="false" />
32
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/__main__.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/__main__.py" afterDir="false" />
33
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/auth/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/auth/__init__.py" afterDir="false" />
34
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/auth/audit_logger.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/auth/audit_logger.py" afterDir="false" />
35
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/auth/oauth_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/auth/oauth_handler.py" afterDir="false" />
36
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/auth/secure_oauth_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/auth/secure_oauth_handler.py" afterDir="false" />
37
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/auth/security_enhancements.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/auth/security_enhancements.py" afterDir="false" />
38
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/auth/security_middleware.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/auth/security_middleware.py" afterDir="false" />
39
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/activities.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/activities.py" afterDir="false" />
40
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/block.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/block.py" afterDir="false" />
41
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/cashiering.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/cashiering.py" afterDir="false" />
42
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/crm.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/crm.py" afterDir="false" />
43
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/front_office.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/front_office.py" afterDir="false" />
44
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/housekeeping.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/housekeeping.py" afterDir="false" />
45
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/inventory.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/inventory.py" afterDir="false" />
46
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/rates.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/rates.py" afterDir="false" />
47
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/reservations.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/api_clients/reservations.py" afterDir="false" />
48
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/base_client.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/base_client.py" afterDir="false" />
49
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/clients/client_factory.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/clients/client_factory.py" afterDir="false" />
50
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/config/security_settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/config/security_settings.py" afterDir="false" />
51
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/config/settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/config/settings.py" afterDir="false" />
52
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/main.py" afterDir="false" />
53
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/models/common.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/models/common.py" afterDir="false" />
54
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/models/reservation.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/models/reservation.py" afterDir="false" />
55
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/resources/api_specs.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/resources/api_specs.py" afterDir="false" />
56
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/resources/health_check.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/resources/health_check.py" afterDir="false" />
57
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/server.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/server.py" afterDir="false" />
58
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/tools/financial_tools.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/tools/financial_tools.py" afterDir="false" />
59
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/tools/guest_tools.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/tools/guest_tools.py" afterDir="false" />
60
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/tools/operation_tools.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/tools/operation_tools.py" afterDir="false" />
61
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/tools/reservation_tools.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/tools/reservation_tools.py" afterDir="false" />
62
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/tools/room_tools.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/tools/room_tools.py" afterDir="false" />
63
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/tools/tool_registry.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/tools/tool_registry.py" afterDir="false" />
64
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/utils/cache_manager.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/utils/cache_manager.py" afterDir="false" />
65
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/utils/client_factory.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/utils/client_factory.py" afterDir="false" />
66
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/utils/connection_optimizer.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/utils/connection_optimizer.py" afterDir="false" />
67
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/utils/exceptions.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/utils/exceptions.py" afterDir="false" />
68
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/utils/formatters.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/utils/formatters.py" afterDir="false" />
69
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/utils/observability.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/utils/observability.py" afterDir="false" />
70
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/utils/resilience_manager.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/utils/resilience_manager.py" afterDir="false" />
71
+ <change beforePath="$PROJECT_DIR$/opera_cloud_mcp/utils/validators.py" beforeDir="false" afterPath="$PROJECT_DIR$/opera_cloud_mcp/utils/validators.py" afterDir="false" />
72
+ <change beforePath="$PROJECT_DIR$/pyproject.toml" beforeDir="false" afterPath="$PROJECT_DIR$/pyproject.toml" afterDir="false" />
73
+ <change beforePath="$PROJECT_DIR$/tests/conftest.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/conftest.py" afterDir="false" />
74
+ <change beforePath="$PROJECT_DIR$/tests/integration/test_main_integration.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/integration/test_main_integration.py" afterDir="false" />
75
+ <change beforePath="$PROJECT_DIR$/tests/performance/load_test.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/performance/load_test.py" afterDir="false" />
76
+ <change beforePath="$PROJECT_DIR$/tests/performance/test_performance.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/performance/test_performance.py" afterDir="false" />
77
+ <change beforePath="$PROJECT_DIR$/tests/unit/test_activities_client.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/unit/test_activities_client.py" afterDir="false" />
78
+ <change beforePath="$PROJECT_DIR$/tests/unit/test_api_specs.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/unit/test_api_specs.py" afterDir="false" />
79
+ <change beforePath="$PROJECT_DIR$/tests/unit/test_enhanced_oauth_integration.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/unit/test_enhanced_oauth_integration.py" afterDir="false" />
80
+ <change beforePath="$PROJECT_DIR$/tests/unit/test_front_office_client.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/unit/test_front_office_client.py" afterDir="false" />
81
+ <change beforePath="$PROJECT_DIR$/tests/unit/test_models.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/unit/test_models.py" afterDir="false" />
82
+ <change beforePath="$PROJECT_DIR$/tests/unit/test_reservation_models.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/unit/test_reservation_models.py" afterDir="false" />
83
+ <change beforePath="$PROJECT_DIR$/tests/unit/test_reservation_tools.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/unit/test_reservation_tools.py" afterDir="false" />
84
+ <change beforePath="$PROJECT_DIR$/tests/unit/test_reservations_client.py" beforeDir="false" afterPath="$PROJECT_DIR$/tests/unit/test_reservations_client.py" afterDir="false" />
85
+ <change beforePath="$PROJECT_DIR$/uv.lock" beforeDir="false" afterPath="$PROJECT_DIR$/uv.lock" afterDir="false" />
86
+ </list>
87
+ <option name="SHOW_DIALOG" value="false" />
88
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
89
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
90
+ <option name="LAST_RESOLUTION" value="IGNORE" />
91
+ </component>
92
+ <component name="FlaskConsoleOptions" custom-start-script="import sys; print('Python %s on %s' % (sys.version, sys.platform)); sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])&#10;from flask.cli import ScriptInfo, NoAppException&#10;for module in [&quot;main.py&quot;, &quot;wsgi.py&quot;, &quot;app.py&quot;]:&#10; try: locals().update(ScriptInfo(app_import_path=module, create_app=None).load_app().make_shell_context()); print(&quot;\nFlask App: %s&quot; % app.import_name); break&#10; except NoAppException: pass">
93
+ <envs>
94
+ <env key="FLASK_APP" value="app" />
95
+ </envs>
96
+ <option name="myCustomStartScript" value="import sys; print('Python %s on %s' % (sys.version, sys.platform)); sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])&#10;from flask.cli import ScriptInfo, NoAppException&#10;for module in [&quot;main.py&quot;, &quot;wsgi.py&quot;, &quot;app.py&quot;]:&#10; try: locals().update(ScriptInfo(app_import_path=module, create_app=None).load_app().make_shell_context()); print(&quot;\nFlask App: %s&quot; % app.import_name); break&#10; except NoAppException: pass" />
97
+ <option name="myEnvs">
98
+ <map>
99
+ <entry key="FLASK_APP" value="app" />
100
+ </map>
101
+ </option>
102
+ </component>
103
+ <component name="Git.Settings">
104
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
105
+ </component>
106
+ <component name="GitLabMergeRequestFiltersHistory">{
107
+ &quot;lastFilter&quot;: {
108
+ &quot;state&quot;: &quot;OPENED&quot;,
109
+ &quot;assignee&quot;: {
110
+ &quot;type&quot;: &quot;org.jetbrains.plugins.gitlab.mergerequest.ui.filters.GitLabMergeRequestsFiltersValue.MergeRequestsMemberFilterValue.MergeRequestsAssigneeFilterValue&quot;,
111
+ &quot;username&quot;: &quot;lesleslie&quot;,
112
+ &quot;fullname&quot;: &quot;Les Leslie&quot;
113
+ }
114
+ }
115
+ }</component>
116
+ <component name="GitLabMergeRequestsSettings">{
117
+ &quot;selectedUrlAndAccountId&quot;: {
118
+ &quot;first&quot;: &quot;https://gitlab.com/lesleslie/opera-cloud-mcp.git&quot;,
119
+ &quot;second&quot;: &quot;97b5872b-7573-42a7-9547-7db3d03839d1&quot;
120
+ }
121
+ }</component>
122
+ <component name="HighlightingSettingsPerFile">
123
+ <setting file="file://$PROJECT_DIR$/.mcp.json" root0="FORCE_HIGHLIGHTING" />
124
+ <setting file="file://$PROJECT_DIR$/README.md" root0="FORCE_HIGHLIGHTING" root1="FORCE_HIGHLIGHTING" />
125
+ <setting file="file://$PROJECT_DIR$/pyproject.toml" root0="FORCE_HIGHLIGHTING" />
126
+ </component>
127
+ <component name="ProjectColorInfo">{
128
+ &quot;associatedIndex&quot;: 2
129
+ }</component>
130
+ <component name="ProjectId" id="3296G49LB868YsLukimO47t6fW2" />
131
+ <component name="ProjectViewState">
132
+ <option name="hideEmptyMiddlePackages" value="true" />
133
+ <option name="showLibraryContents" value="true" />
134
+ </component>
135
+ <component name="PropertiesComponent">{
136
+ &quot;keyToString&quot;: {
137
+ &quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
138
+ &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
139
+ &quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
140
+ &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
141
+ &quot;dart.analysis.tool.window.visible&quot;: &quot;false&quot;,
142
+ &quot;git-widget-placeholder&quot;: &quot;main&quot;,
143
+ &quot;last_opened_file_path&quot;: &quot;/Users/les/Projects/opera-cloud-mcp&quot;,
144
+ &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
145
+ &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
146
+ &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
147
+ &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
148
+ &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
149
+ &quot;settings.editor.selected.configurable&quot;: &quot;com.intellij.pycharm.community.ide.impl.configuration.PythonContentEntriesConfigurable&quot;,
150
+ &quot;show.migrate.to.gradle.popup&quot;: &quot;false&quot;,
151
+ &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
152
+ }
153
+ }</component>
154
+ <component name="PyConsoleOptionsProvider">
155
+ <option name="myPythonConsoleState">
156
+ <console-settings module-name="opera-cloud-mcp" is-module-sdk="true">
157
+ <option name="myUseModuleSdk" value="true" />
158
+ <option name="myModuleName" value="opera-cloud-mcp" />
159
+ </console-settings>
160
+ </option>
161
+ </component>
162
+ <component name="RecentsManager">
163
+ <key name="CopyFile.RECENT_KEYS">
164
+ <recent name="$PROJECT_DIR$" />
165
+ </key>
166
+ <key name="MoveFile.RECENT_KEYS">
167
+ <recent name="$PROJECT_DIR$" />
168
+ </key>
169
+ </component>
170
+ <component name="SharedIndexes">
171
+ <attachedChunks>
172
+ <set>
173
+ <option value="bundled-js-predefined-d6986cc7102b-b598e85cdad2-JavaScript-PY-252.25557.178" />
174
+ <option value="bundled-python-sdk-ce6832f46686-7b97d883f26b-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-252.25557.178" />
175
+ </set>
176
+ </attachedChunks>
177
+ </component>
178
+ <component name="TaskManager">
179
+ <task active="true" id="Default" summary="Default task">
180
+ <changelist id="af953397-b617-4550-a2f9-24aa65c57a56" name="Changes" comment="" />
181
+ <created>1756820342011</created>
182
+ <option name="number" value="Default" />
183
+ <option name="presentableId" value="Default" />
184
+ <updated>1756820342011</updated>
185
+ <workItem from="1756820343411" duration="27178000" />
186
+ <workItem from="1756936088002" duration="3706000" />
187
+ <workItem from="1757182647187" duration="396000" />
188
+ <workItem from="1757231067608" duration="559000" />
189
+ <workItem from="1757231680943" duration="523000" />
190
+ <workItem from="1757237092113" duration="2017000" />
191
+ <workItem from="1757298154339" duration="577000" />
192
+ <workItem from="1757404548984" duration="581000" />
193
+ <workItem from="1758005217998" duration="7617000" />
194
+ <workItem from="1758180716528" duration="3625000" />
195
+ <workItem from="1758242068984" duration="6718000" />
196
+ <workItem from="1758284784793" duration="3800000" />
197
+ <workItem from="1758341588710" duration="3183000" />
198
+ <workItem from="1758379800784" duration="587000" />
199
+ <workItem from="1758380635081" duration="1979000" />
200
+ <workItem from="1758383518684" duration="2586000" />
201
+ <workItem from="1758402653329" duration="1090000" />
202
+ </task>
203
+ <servers />
204
+ </component>
205
+ <component name="TypeScriptGeneratedFilesManager">
206
+ <option name="version" value="3" />
207
+ </component>
208
+ </project>
@@ -0,0 +1,109 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: validate-regex-patterns
5
+ name: validate-regex-patterns
6
+ entry: uv run python -m crackerjack.tools.validate_regex_patterns
7
+ language: system
8
+ files: \.py$
9
+ exclude: ^\.venv/|^src/
10
+ - id: skylos
11
+ name: skylos-dead-code-detection
12
+ entry: skylos
13
+ language: system
14
+ args: ["opera_cloud_mcp", "--exclude", "tests"]
15
+ pass_filenames: false
16
+ exclude: ^tests/|^src/
17
+ stages: ["pre-push", "manual"]
18
+ - id: zuban
19
+ name: zuban-type-checking
20
+ entry: uv run zuban check
21
+ language: system
22
+ args: ["--config-file", "mypy.ini", "./opera_cloud_mcp"]
23
+ pass_filenames: false
24
+ exclude: ^tests/|^src/
25
+ stages: ["pre-push", "manual"]
26
+ - id: pyright
27
+ name: pyright-type-checking
28
+ entry: uv run pyright
29
+ language: system
30
+ files: ^opera_cloud_mcp/.*\.py$
31
+ exclude: ^crackerjack/(mcp|plugins)/.*\.py$|crackerjack/code_cleaner\.py$|^src/
32
+ stages: ["pre-push", "manual"]
33
+ - repo: https://github.com/pre-commit/pre-commit-hooks
34
+ rev: v6.0.0
35
+ hooks:
36
+ - id: trailing-whitespace
37
+ name: trailing-whitespace
38
+ exclude: ^\.venv/|^src/
39
+ - id: end-of-file-fixer
40
+ name: end-of-file-fixer
41
+ exclude: ^\.venv/|^src/
42
+ - id: check-yaml
43
+ name: check-yaml
44
+ exclude: ^\.venv/|^src/
45
+ - id: check-toml
46
+ name: check-toml
47
+ exclude: ^\.venv/|^src/
48
+ - id: check-added-large-files
49
+ name: check-added-large-files
50
+ exclude: ^\.venv/|^src/
51
+ - repo: https://github.com/astral-sh/uv-pre-commit
52
+ rev: 0.8.15
53
+ hooks:
54
+ - id: uv-lock
55
+ files: ^ pyproject\.toml$
56
+ exclude: ^src/
57
+ - repo: https://github.com/gitleaks/gitleaks
58
+ rev: v8.28.0
59
+ hooks:
60
+ - id: gitleaks
61
+ exclude: uv\.lock|pyproject\.toml|tests/.*|docs/.*|.*\.md|^src/
62
+ - repo: https://github.com/PyCQA/bandit
63
+ rev: 1.8.6
64
+ hooks:
65
+ - id: bandit
66
+ args: ["-c", "pyproject.toml", "-r", "-ll"]
67
+ files: ^opera_cloud_mcp/.*\.py$
68
+ exclude: ^tests/|^src/
69
+ stages: ["pre-push", "manual"]
70
+ - repo: https://github.com/codespell-project/codespell
71
+ rev: v2.4.1
72
+ hooks:
73
+ - id: codespell
74
+ exclude: ^\.venv/|^src/
75
+ additional_dependencies: ["tomli"]
76
+ - repo: https://github.com/astral-sh/ruff-pre-commit
77
+ rev: v0.12.12
78
+ hooks:
79
+ - id: ruff-check
80
+ exclude: ^\.venv/|^src/
81
+ - id: ruff-format
82
+ exclude: ^\.venv/|^src/
83
+ - repo: https://github.com/executablebooks/mdformat
84
+ rev: 0.7.22
85
+ hooks:
86
+ - id: mdformat
87
+ exclude: ^\.venv/|^src/
88
+ additional_dependencies: ["mdformat-ruff"]
89
+ - repo: https://github.com/fredrikaverpil/creosote
90
+ rev: v4.1.0
91
+ hooks:
92
+ - id: creosote
93
+ exclude: ^\.venv/|^src/
94
+ stages: ["pre-push", "manual"]
95
+ - repo: https://github.com/rohaquinlop/complexipy-pre-commit
96
+ rev: v3.3.0
97
+ hooks:
98
+ - id: complexipy
99
+ args: ["-d", "low", "--max-complexity-allowed", "15"]
100
+ files: ^opera_cloud_mcp/.*\.py$
101
+ exclude: ^(\.venv/|tests/)|^src/
102
+ stages: ["pre-push", "manual"]
103
+ - repo: https://github.com/dosisod/refurb
104
+ rev: v2.1.0
105
+ hooks:
106
+ - id: refurb
107
+ files: ^opera_cloud_mcp/.*\.py$
108
+ exclude: ^tests/|^src/
109
+ stages: ["pre-push", "manual"]