mcp-proxy-adapter 6.3.4__py3-none-any.whl → 6.3.5__py3-none-any.whl

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 (129) hide show
  1. mcp_proxy_adapter/__init__.py +9 -5
  2. mcp_proxy_adapter/__main__.py +1 -1
  3. mcp_proxy_adapter/api/app.py +227 -176
  4. mcp_proxy_adapter/api/handlers.py +68 -60
  5. mcp_proxy_adapter/api/middleware/__init__.py +7 -5
  6. mcp_proxy_adapter/api/middleware/base.py +19 -16
  7. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +44 -34
  8. mcp_proxy_adapter/api/middleware/error_handling.py +57 -67
  9. mcp_proxy_adapter/api/middleware/factory.py +50 -52
  10. mcp_proxy_adapter/api/middleware/logging.py +46 -30
  11. mcp_proxy_adapter/api/middleware/performance.py +19 -16
  12. mcp_proxy_adapter/api/middleware/protocol_middleware.py +80 -50
  13. mcp_proxy_adapter/api/middleware/transport_middleware.py +26 -24
  14. mcp_proxy_adapter/api/middleware/unified_security.py +70 -51
  15. mcp_proxy_adapter/api/middleware/user_info_middleware.py +43 -34
  16. mcp_proxy_adapter/api/schemas.py +69 -43
  17. mcp_proxy_adapter/api/tool_integration.py +83 -63
  18. mcp_proxy_adapter/api/tools.py +60 -50
  19. mcp_proxy_adapter/commands/__init__.py +15 -6
  20. mcp_proxy_adapter/commands/auth_validation_command.py +107 -110
  21. mcp_proxy_adapter/commands/base.py +108 -112
  22. mcp_proxy_adapter/commands/builtin_commands.py +28 -18
  23. mcp_proxy_adapter/commands/catalog_manager.py +394 -265
  24. mcp_proxy_adapter/commands/cert_monitor_command.py +222 -204
  25. mcp_proxy_adapter/commands/certificate_management_command.py +210 -213
  26. mcp_proxy_adapter/commands/command_registry.py +275 -226
  27. mcp_proxy_adapter/commands/config_command.py +48 -33
  28. mcp_proxy_adapter/commands/dependency_container.py +22 -23
  29. mcp_proxy_adapter/commands/dependency_manager.py +65 -56
  30. mcp_proxy_adapter/commands/echo_command.py +15 -15
  31. mcp_proxy_adapter/commands/health_command.py +31 -29
  32. mcp_proxy_adapter/commands/help_command.py +97 -61
  33. mcp_proxy_adapter/commands/hooks.py +65 -49
  34. mcp_proxy_adapter/commands/key_management_command.py +148 -147
  35. mcp_proxy_adapter/commands/load_command.py +58 -40
  36. mcp_proxy_adapter/commands/plugins_command.py +80 -54
  37. mcp_proxy_adapter/commands/protocol_management_command.py +60 -48
  38. mcp_proxy_adapter/commands/proxy_registration_command.py +107 -115
  39. mcp_proxy_adapter/commands/reload_command.py +43 -37
  40. mcp_proxy_adapter/commands/result.py +26 -33
  41. mcp_proxy_adapter/commands/role_test_command.py +26 -26
  42. mcp_proxy_adapter/commands/roles_management_command.py +176 -173
  43. mcp_proxy_adapter/commands/security_command.py +134 -122
  44. mcp_proxy_adapter/commands/settings_command.py +47 -56
  45. mcp_proxy_adapter/commands/ssl_setup_command.py +109 -129
  46. mcp_proxy_adapter/commands/token_management_command.py +129 -158
  47. mcp_proxy_adapter/commands/transport_management_command.py +41 -36
  48. mcp_proxy_adapter/commands/unload_command.py +42 -37
  49. mcp_proxy_adapter/config.py +36 -35
  50. mcp_proxy_adapter/core/__init__.py +19 -21
  51. mcp_proxy_adapter/core/app_factory.py +30 -9
  52. mcp_proxy_adapter/core/app_runner.py +81 -64
  53. mcp_proxy_adapter/core/auth_validator.py +176 -182
  54. mcp_proxy_adapter/core/certificate_utils.py +469 -426
  55. mcp_proxy_adapter/core/client.py +155 -126
  56. mcp_proxy_adapter/core/client_manager.py +60 -54
  57. mcp_proxy_adapter/core/client_security.py +108 -88
  58. mcp_proxy_adapter/core/config_converter.py +176 -143
  59. mcp_proxy_adapter/core/config_validator.py +12 -4
  60. mcp_proxy_adapter/core/crl_utils.py +21 -7
  61. mcp_proxy_adapter/core/errors.py +64 -20
  62. mcp_proxy_adapter/core/logging.py +34 -29
  63. mcp_proxy_adapter/core/mtls_asgi.py +29 -25
  64. mcp_proxy_adapter/core/mtls_asgi_app.py +66 -54
  65. mcp_proxy_adapter/core/protocol_manager.py +154 -104
  66. mcp_proxy_adapter/core/proxy_client.py +202 -144
  67. mcp_proxy_adapter/core/proxy_registration.py +7 -3
  68. mcp_proxy_adapter/core/role_utils.py +139 -125
  69. mcp_proxy_adapter/core/security_adapter.py +88 -77
  70. mcp_proxy_adapter/core/security_factory.py +50 -44
  71. mcp_proxy_adapter/core/security_integration.py +72 -24
  72. mcp_proxy_adapter/core/server_adapter.py +68 -64
  73. mcp_proxy_adapter/core/server_engine.py +71 -53
  74. mcp_proxy_adapter/core/settings.py +68 -58
  75. mcp_proxy_adapter/core/ssl_utils.py +69 -56
  76. mcp_proxy_adapter/core/transport_manager.py +72 -60
  77. mcp_proxy_adapter/core/unified_config_adapter.py +201 -150
  78. mcp_proxy_adapter/core/utils.py +4 -2
  79. mcp_proxy_adapter/custom_openapi.py +107 -99
  80. mcp_proxy_adapter/examples/basic_framework/main.py +9 -2
  81. mcp_proxy_adapter/examples/commands/__init__.py +1 -1
  82. mcp_proxy_adapter/examples/create_certificates_simple.py +182 -71
  83. mcp_proxy_adapter/examples/debug_request_state.py +38 -19
  84. mcp_proxy_adapter/examples/debug_role_chain.py +53 -20
  85. mcp_proxy_adapter/examples/demo_client.py +48 -36
  86. mcp_proxy_adapter/examples/examples/basic_framework/main.py +9 -2
  87. mcp_proxy_adapter/examples/examples/full_application/__init__.py +1 -0
  88. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +22 -10
  89. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +24 -17
  90. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +16 -3
  91. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +13 -3
  92. mcp_proxy_adapter/examples/examples/full_application/main.py +27 -2
  93. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +48 -14
  94. mcp_proxy_adapter/examples/full_application/__init__.py +1 -0
  95. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +22 -10
  96. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +24 -17
  97. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +16 -3
  98. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +13 -3
  99. mcp_proxy_adapter/examples/full_application/main.py +27 -2
  100. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +48 -14
  101. mcp_proxy_adapter/examples/generate_all_certificates.py +198 -73
  102. mcp_proxy_adapter/examples/generate_certificates.py +31 -16
  103. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +220 -74
  104. mcp_proxy_adapter/examples/generate_test_configs.py +68 -91
  105. mcp_proxy_adapter/examples/proxy_registration_example.py +76 -75
  106. mcp_proxy_adapter/examples/run_example.py +23 -5
  107. mcp_proxy_adapter/examples/run_full_test_suite.py +109 -71
  108. mcp_proxy_adapter/examples/run_proxy_server.py +22 -9
  109. mcp_proxy_adapter/examples/run_security_tests.py +103 -41
  110. mcp_proxy_adapter/examples/run_security_tests_fixed.py +72 -36
  111. mcp_proxy_adapter/examples/scripts/config_generator.py +288 -187
  112. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +185 -72
  113. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +220 -74
  114. mcp_proxy_adapter/examples/security_test_client.py +196 -127
  115. mcp_proxy_adapter/examples/setup_test_environment.py +17 -29
  116. mcp_proxy_adapter/examples/test_config.py +19 -4
  117. mcp_proxy_adapter/examples/test_config_generator.py +23 -7
  118. mcp_proxy_adapter/examples/test_examples.py +84 -56
  119. mcp_proxy_adapter/examples/universal_client.py +119 -62
  120. mcp_proxy_adapter/openapi.py +108 -115
  121. mcp_proxy_adapter/utils/config_generator.py +429 -274
  122. mcp_proxy_adapter/version.py +1 -2
  123. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/METADATA +1 -1
  124. mcp_proxy_adapter-6.3.5.dist-info/RECORD +143 -0
  125. mcp_proxy_adapter-6.3.4.dist-info/RECORD +0 -143
  126. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/WHEEL +0 -0
  127. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/entry_points.txt +0 -0
  128. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/licenses/LICENSE +0 -0
  129. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/top_level.txt +0 -0
@@ -19,11 +19,13 @@ class HealthResult(SuccessResult):
19
19
  """
20
20
  Result of the health command execution.
21
21
  """
22
-
23
- def __init__(self, status: str, version: str, uptime: float, components: Dict[str, Any]):
22
+
23
+ def __init__(
24
+ self, status: str, version: str, uptime: float, components: Dict[str, Any]
25
+ ):
24
26
  """
25
27
  Initialize health command result.
26
-
28
+
27
29
  Args:
28
30
  status: Server status ("ok" or "error")
29
31
  version: Server version
@@ -35,15 +37,15 @@ class HealthResult(SuccessResult):
35
37
  "status": status,
36
38
  "version": version,
37
39
  "uptime": uptime,
38
- "components": components
40
+ "components": components,
39
41
  }
40
42
  )
41
-
43
+
42
44
  @classmethod
43
45
  def get_schema(cls) -> Dict[str, Any]:
44
46
  """
45
47
  Get JSON schema for result validation.
46
-
48
+
47
49
  Returns:
48
50
  Dict[str, Any]: JSON schema
49
51
  """
@@ -61,14 +63,14 @@ class HealthResult(SuccessResult):
61
63
  "properties": {
62
64
  "system": {"type": "object"},
63
65
  "process": {"type": "object"},
64
- "commands": {"type": "object"}
65
- }
66
- }
66
+ "commands": {"type": "object"},
67
+ },
68
+ },
67
69
  },
68
- "required": ["status", "version", "uptime", "components"]
70
+ "required": ["status", "version", "uptime", "components"],
69
71
  }
70
72
  },
71
- "required": ["data"]
73
+ "required": ["data"],
72
74
  }
73
75
 
74
76
 
@@ -76,14 +78,14 @@ class HealthCommand(Command):
76
78
  """
77
79
  Command that returns information about server health and status.
78
80
  """
79
-
81
+
80
82
  name = "health"
81
83
  result_class = HealthResult
82
-
84
+
83
85
  async def execute(self, **kwargs) -> HealthResult:
84
86
  """
85
87
  Execute health command.
86
-
88
+
87
89
  Returns:
88
90
  HealthResult: Health command result
89
91
  """
@@ -92,15 +94,15 @@ class HealthCommand(Command):
92
94
  from mcp_proxy_adapter.version import __version__ as version
93
95
  except ImportError:
94
96
  version = "unknown"
95
-
97
+
96
98
  # Get process start time
97
99
  process = psutil.Process(os.getpid())
98
100
  start_time = datetime.fromtimestamp(process.create_time())
99
101
  uptime_seconds = (datetime.now() - start_time).total_seconds()
100
-
102
+
101
103
  # Get system information
102
104
  memory_info = process.memory_info()
103
-
105
+
104
106
  return HealthResult(
105
107
  status="ok",
106
108
  version=version,
@@ -109,35 +111,35 @@ class HealthCommand(Command):
109
111
  "system": {
110
112
  "python_version": sys.version,
111
113
  "platform": platform.platform(),
112
- "cpu_count": os.cpu_count()
114
+ "cpu_count": os.cpu_count(),
113
115
  },
114
116
  "process": {
115
117
  "pid": os.getpid(),
116
118
  "memory_usage_mb": memory_info.rss / (1024 * 1024),
117
- "start_time": start_time.isoformat()
118
- },
119
- "commands": {
120
- "registered_count": len(registry.get_all_commands())
119
+ "start_time": start_time.isoformat(),
121
120
  },
121
+ "commands": {"registered_count": len(registry.get_all_commands())},
122
122
  "proxy_registration": {
123
123
  "enabled": get_proxy_registration_status().get("enabled", False),
124
- "registered": get_proxy_registration_status().get("registered", False),
124
+ "registered": get_proxy_registration_status().get(
125
+ "registered", False
126
+ ),
125
127
  "server_key": get_proxy_registration_status().get("server_key"),
126
- "proxy_url": get_proxy_registration_status().get("proxy_url")
127
- }
128
- }
128
+ "proxy_url": get_proxy_registration_status().get("proxy_url"),
129
+ },
130
+ },
129
131
  )
130
-
132
+
131
133
  @classmethod
132
134
  def get_schema(cls) -> Dict[str, Any]:
133
135
  """
134
136
  Get JSON schema for command parameters validation.
135
-
137
+
136
138
  Returns:
137
139
  Dict[str, Any]: JSON schema
138
140
  """
139
141
  return {
140
142
  "type": "object",
141
143
  "additionalProperties": False,
142
- "description": "Command doesn't accept any parameters"
144
+ "description": "Command doesn't accept any parameters",
143
145
  }
@@ -20,7 +20,11 @@ class HelpResult(CommandResult):
20
20
  Result of the help command execution.
21
21
  """
22
22
 
23
- def __init__(self, commands_info: Optional[Dict[str, Any]] = None, command_info: Optional[Dict[str, Any]] = None):
23
+ def __init__(
24
+ self,
25
+ commands_info: Optional[Dict[str, Any]] = None,
26
+ command_info: Optional[Dict[str, Any]] = None,
27
+ ):
24
28
  """
25
29
  Initialize help command result.
26
30
 
@@ -28,7 +32,9 @@ class HelpResult(CommandResult):
28
32
  commands_info: Information about all commands (for request without parameters)
29
33
  command_info: Information about a specific command (for request with cmdname parameter)
30
34
  """
31
- logger.debug(f"HelpResult.__init__: commands_info={commands_info is not None}, command_info={command_info is not None}")
35
+ logger.debug(
36
+ f"HelpResult.__init__: commands_info={commands_info is not None}, command_info={command_info is not None}"
37
+ )
32
38
  self.commands_info = commands_info
33
39
  self.command_info = command_info
34
40
 
@@ -40,11 +46,15 @@ class HelpResult(CommandResult):
40
46
  Dict[str, Any]: Result as dictionary
41
47
  """
42
48
  try:
43
- logger.debug(f"HelpResult.to_dict: command_info={self.command_info is not None}, commands_info={self.commands_info is not None}")
49
+ logger.debug(
50
+ f"HelpResult.to_dict: command_info={self.command_info is not None}, commands_info={self.commands_info is not None}"
51
+ )
44
52
 
45
53
  # Защита от None для self.command_info
46
54
  if self.command_info is not None:
47
- logger.debug(f"HelpResult.to_dict: returning command_info for {self.command_info.get('name', 'unknown')}")
55
+ logger.debug(
56
+ f"HelpResult.to_dict: returning command_info for {self.command_info.get('name', 'unknown')}"
57
+ )
48
58
  # Делаем безопасное получение всех полей с дефолтными значениями
49
59
  metadata = self.command_info.get("metadata", {})
50
60
  schema = self.command_info.get("schema", {})
@@ -54,42 +64,57 @@ class HelpResult(CommandResult):
54
64
  "description": metadata.get("description", ""),
55
65
  "summary": metadata.get("summary", ""),
56
66
  "params": schema.get("properties", {}),
57
- "examples": metadata.get("examples", [])
58
- }
67
+ "examples": metadata.get("examples", []),
68
+ },
59
69
  }
60
70
 
61
71
  # Защита от None для self.commands_info
62
72
  if self.commands_info is None:
63
- logger.warning("HelpResult.to_dict: commands_info is None, создаем пустой результат")
73
+ logger.warning(
74
+ "HelpResult.to_dict: commands_info is None, создаем пустой результат"
75
+ )
64
76
  # Возвращаем пустой список команд вместо ошибки
65
77
  return {
66
78
  "tool_info": {
67
79
  "name": "MCP-Proxy API Service",
68
80
  "description": "JSON-RPC API for microservice command execution",
69
- "version": "1.0.0"
81
+ "version": "1.0.0",
70
82
  },
71
83
  "help_usage": {
72
84
  "description": "Get information about commands",
73
85
  "examples": [
74
- {"command": "help", "description": "List of all available commands"},
75
- {"command": "help", "params": {"cmdname": "command_name"}, "description": "Get detailed information about a specific command"}
76
- ]
86
+ {
87
+ "command": "help",
88
+ "description": "List of all available commands",
89
+ },
90
+ {
91
+ "command": "help",
92
+ "params": {"cmdname": "command_name"},
93
+ "description": "Get detailed information about a specific command",
94
+ },
95
+ ],
77
96
  },
78
97
  "commands": {},
79
98
  "total": 0,
80
- "note": "To get detailed information about a specific command, call help with parameter: POST /cmd {\"command\": \"help\", \"params\": {\"cmdname\": \"<command_name>\"}}"
99
+ "note": 'To get detailed information about a specific command, call help with parameter: POST /cmd {"command": "help", "params": {"cmdname": "<command_name>"}}',
81
100
  }
82
101
 
83
102
  # For list of all commands, return as is (already formatted)
84
- logger.debug(f"HelpResult.to_dict: processing commands_info with {len(self.commands_info.get('commands', {}))} commands")
103
+ logger.debug(
104
+ f"HelpResult.to_dict: processing commands_info with {len(self.commands_info.get('commands', {}))} commands"
105
+ )
85
106
  result = self.commands_info.copy()
86
107
 
87
108
  # Add total count and note about usage
88
109
  commands = result.get("commands", {})
89
110
  result["total"] = len(commands)
90
- result["note"] = "To get detailed information about a specific command, call help with parameter: POST /cmd {\"command\": \"help\", \"params\": {\"cmdname\": \"<command_name>\"}}"
111
+ result["note"] = (
112
+ 'To get detailed information about a specific command, call help with parameter: POST /cmd {"command": "help", "params": {"cmdname": "<command_name>"}}'
113
+ )
91
114
 
92
- logger.debug(f"HelpResult.to_dict: returning result with {result['total']} commands")
115
+ logger.debug(
116
+ f"HelpResult.to_dict: returning result with {result['total']} commands"
117
+ )
93
118
  return result
94
119
  except Exception as e:
95
120
  logger.error(f"Ошибка в HelpResult.to_dict: {e}")
@@ -99,11 +124,11 @@ class HelpResult(CommandResult):
99
124
  "tool_info": {
100
125
  "name": "MCP-Proxy API Service",
101
126
  "description": "JSON-RPC API for microservice command execution",
102
- "version": "1.0.0"
127
+ "version": "1.0.0",
103
128
  },
104
129
  "commands": {},
105
130
  "total": 0,
106
- "error": str(e)
131
+ "error": str(e),
107
132
  }
108
133
 
109
134
  @classmethod
@@ -123,26 +148,22 @@ class HelpResult(CommandResult):
123
148
  "type": "object",
124
149
  "additionalProperties": {
125
150
  "type": "object",
126
- "properties": {
127
- "description": {"type": "string"}
128
- }
129
- }
151
+ "properties": {"description": {"type": "string"}},
152
+ },
130
153
  },
131
154
  "tool_info": {
132
155
  "type": "object",
133
156
  "properties": {
134
157
  "name": {"type": "string"},
135
158
  "description": {"type": "string"},
136
- "version": {"type": "string"}
137
- }
138
- },
139
- "help_usage": {
140
- "type": "object"
159
+ "version": {"type": "string"},
160
+ },
141
161
  },
162
+ "help_usage": {"type": "object"},
142
163
  "total": {"type": "integer"},
143
- "note": {"type": "string"}
164
+ "note": {"type": "string"},
144
165
  },
145
- "required": ["commands"]
166
+ "required": ["commands"],
146
167
  },
147
168
  {
148
169
  "properties": {
@@ -153,13 +174,13 @@ class HelpResult(CommandResult):
153
174
  "description": {"type": "string"},
154
175
  "summary": {"type": "string"},
155
176
  "params": {"type": "object"},
156
- "examples": {"type": "array"}
157
- }
158
- }
177
+ "examples": {"type": "array"},
178
+ },
179
+ },
159
180
  },
160
- "required": ["cmdname", "info"]
161
- }
162
- ]
181
+ "required": ["cmdname", "info"],
182
+ },
183
+ ],
163
184
  }
164
185
 
165
186
 
@@ -206,41 +227,52 @@ class HelpCommand(Command):
206
227
  example_cmd = all_commands[0]
207
228
  example = {
208
229
  "command": "help",
209
- "params": {"cmdname": example_cmd}
230
+ "params": {"cmdname": example_cmd},
210
231
  }
211
232
  note = f"Use help with an existing command name to get detailed info. For example: help with cmdname '{example_cmd}'. To list all commands: call help without parameters."
212
233
  else:
213
234
  example = {"command": "help"}
214
235
  note = "No commands registered. To list all commands: call help without parameters."
215
- return HelpResult(commands_info={
216
- "commands": {},
217
- "error": f"Command '{cmdname}' not found",
218
- "example": example,
219
- "note": note
220
- })
236
+ return HelpResult(
237
+ commands_info={
238
+ "commands": {},
239
+ "error": f"Command '{cmdname}' not found",
240
+ "example": example,
241
+ "note": note,
242
+ }
243
+ )
221
244
 
222
245
  # Otherwise, return information about all available commands
223
246
  logger.debug("Обработка запроса для всех команд")
224
247
 
225
248
  # Get info for all commands
226
249
  all_commands_info = registry.get_all_commands_info()
227
- logger.debug(f"Получены метаданные для {len(all_commands_info.get('commands', {}))} команд")
250
+ logger.debug(
251
+ f"Получены метаданные для {len(all_commands_info.get('commands', {}))} команд"
252
+ )
228
253
 
229
254
  # Prepare response format with tool metadata
230
255
  result = {
231
256
  "tool_info": {
232
257
  "name": "MCP-Proxy API Service",
233
258
  "description": "JSON-RPC API for microservice command execution",
234
- "version": "1.0.0"
259
+ "version": "1.0.0",
235
260
  },
236
261
  "help_usage": {
237
262
  "description": "Get information about commands",
238
263
  "examples": [
239
- {"command": "help", "description": "List of all available commands"},
240
- {"command": "help", "params": {"cmdname": "command_name"}, "description": "Get detailed information about a specific command"}
241
- ]
264
+ {
265
+ "command": "help",
266
+ "description": "List of all available commands",
267
+ },
268
+ {
269
+ "command": "help",
270
+ "params": {"cmdname": "command_name"},
271
+ "description": "Get detailed information about a specific command",
272
+ },
273
+ ],
242
274
  },
243
- "commands": {}
275
+ "commands": {},
244
276
  }
245
277
 
246
278
  # Add brief information about commands
@@ -253,7 +285,7 @@ class HelpCommand(Command):
253
285
  schema = command_info.get("schema", {})
254
286
  result["commands"][name] = {
255
287
  "summary": metadata.get("summary", ""),
256
- "params_count": len(schema.get("properties", {}))
288
+ "params_count": len(schema.get("properties", {})),
257
289
  }
258
290
  except Exception as e:
259
291
  logger.error(f"Ошибка при обработке метаданных команды {name}: {e}")
@@ -261,21 +293,25 @@ class HelpCommand(Command):
261
293
  # Пропускаем проблемную команду
262
294
  continue
263
295
 
264
- logger.debug(f"HelpCommand.execute завершение: возвращаем результат с {len(result['commands'])} командами")
296
+ logger.debug(
297
+ f"HelpCommand.execute завершение: возвращаем результат с {len(result['commands'])} командами"
298
+ )
265
299
  return HelpResult(commands_info=result)
266
300
  except Exception as e:
267
301
  logger.error(f"Неожиданная ошибка в HelpCommand.execute: {e}")
268
302
  logger.debug(f"Трассировка: {traceback.format_exc()}")
269
303
  # В случае неожиданной ошибки возвращаем пустой результат вместо ошибки
270
- return HelpResult(commands_info={
271
- "tool_info": {
272
- "name": "MCP-Proxy API Service",
273
- "description": "JSON-RPC API for microservice command execution",
274
- "version": "1.0.0"
275
- },
276
- "commands": {},
277
- "error": str(e)
278
- })
304
+ return HelpResult(
305
+ commands_info={
306
+ "tool_info": {
307
+ "name": "MCP-Proxy API Service",
308
+ "description": "JSON-RPC API for microservice command execution",
309
+ "version": "1.0.0",
310
+ },
311
+ "commands": {},
312
+ "error": str(e),
313
+ }
314
+ )
279
315
 
280
316
  @classmethod
281
317
  def get_schema(cls) -> Dict[str, Any]:
@@ -290,8 +326,8 @@ class HelpCommand(Command):
290
326
  "properties": {
291
327
  "cmdname": {
292
328
  "type": "string",
293
- "description": "Name of command to get information about"
329
+ "description": "Name of command to get information about",
294
330
  }
295
331
  },
296
- "additionalProperties": False
297
- }
332
+ "additionalProperties": False,
333
+ }