mcp-proxy-adapter 6.3.4__py3-none-any.whl → 6.3.6__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 (131) 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 +120 -91
  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.6.dist-info}/METADATA +1 -1
  124. mcp_proxy_adapter-6.3.6.dist-info/RECORD +144 -0
  125. mcp_proxy_adapter-6.3.6.dist-info/top_level.txt +2 -0
  126. mcp_proxy_adapter_issue_package/demonstrate_issue.py +178 -0
  127. mcp_proxy_adapter-6.3.4.dist-info/RECORD +0 -143
  128. mcp_proxy_adapter-6.3.4.dist-info/top_level.txt +0 -1
  129. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.6.dist-info}/WHEEL +0 -0
  130. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.6.dist-info}/entry_points.txt +0 -0
  131. {mcp_proxy_adapter-6.3.4.dist-info → mcp_proxy_adapter-6.3.6.dist-info}/licenses/LICENSE +0 -0
@@ -11,15 +11,19 @@ class ErrorResponse(BaseModel):
11
11
  """
12
12
  Error response model.
13
13
  """
14
+
14
15
  code: int = Field(..., description="Error code")
15
16
  message: str = Field(..., description="Error message")
16
- details: Optional[Dict[str, Any]] = Field(None, description="Additional error details")
17
+ details: Optional[Dict[str, Any]] = Field(
18
+ None, description="Additional error details"
19
+ )
17
20
 
18
21
 
19
22
  class ErrorWrapper(BaseModel):
20
23
  """
21
24
  Wrapper for error response.
22
25
  """
26
+
23
27
  error: ErrorResponse
24
28
 
25
29
 
@@ -27,9 +31,12 @@ class JsonRpcRequest(BaseModel):
27
31
  """
28
32
  JSON-RPC request model.
29
33
  """
34
+
30
35
  jsonrpc: Literal["2.0"] = Field("2.0", description="JSON-RPC version")
31
36
  method: str = Field(..., description="Method name")
32
- params: Optional[Union[Dict[str, Any], List[Any]]] = Field(None, description="Method parameters")
37
+ params: Optional[Union[Dict[str, Any], List[Any]]] = Field(
38
+ None, description="Method parameters"
39
+ )
33
40
  id: Optional[Union[str, int]] = Field(None, description="Request ID")
34
41
 
35
42
 
@@ -37,6 +44,7 @@ class JsonRpcError(BaseModel):
37
44
  """
38
45
  JSON-RPC error model.
39
46
  """
47
+
40
48
  code: int = Field(..., description="Error code")
41
49
  message: str = Field(..., description="Error message")
42
50
  data: Optional[Dict[str, Any]] = Field(None, description="Additional error data")
@@ -46,6 +54,7 @@ class JsonRpcSuccessResponse(BaseModel):
46
54
  """
47
55
  JSON-RPC success response model.
48
56
  """
57
+
49
58
  jsonrpc: Literal["2.0"] = Field("2.0", description="JSON-RPC version")
50
59
  result: Dict[str, Any] = Field(..., description="Method result")
51
60
  id: Optional[Union[str, int]] = Field(None, description="Request ID")
@@ -55,6 +64,7 @@ class JsonRpcErrorResponse(BaseModel):
55
64
  """
56
65
  JSON-RPC error response model.
57
66
  """
67
+
58
68
  jsonrpc: Literal["2.0"] = Field("2.0", description="JSON-RPC version")
59
69
  error: JsonRpcError = Field(..., description="Error information")
60
70
  id: Optional[Union[str, int]] = Field(None, description="Request ID")
@@ -64,6 +74,7 @@ class CommandResponse(BaseModel):
64
74
  """
65
75
  Command response model.
66
76
  """
77
+
67
78
  success: bool = Field(..., description="Command execution success flag")
68
79
  data: Optional[Dict[str, Any]] = Field(None, description="Result data")
69
80
  message: Optional[str] = Field(None, description="Result message")
@@ -74,6 +85,7 @@ class HealthResponse(BaseModel):
74
85
  """
75
86
  Health response model.
76
87
  """
88
+
77
89
  status: str = Field(..., description="Server status")
78
90
  version: str = Field(..., description="Server version")
79
91
  uptime: float = Field(..., description="Server uptime in seconds")
@@ -84,6 +96,7 @@ class CommandListResponse(BaseModel):
84
96
  """
85
97
  Command list response model.
86
98
  """
99
+
87
100
  commands: Dict[str, Dict[str, Any]] = Field(..., description="Available commands")
88
101
 
89
102
 
@@ -91,6 +104,7 @@ class CommandRequest(BaseModel):
91
104
  """
92
105
  Command request model for /cmd endpoint.
93
106
  """
107
+
94
108
  command: str = Field(..., description="Command name to execute")
95
109
  params: Optional[Dict[str, Any]] = Field({}, description="Command parameters")
96
110
 
@@ -99,6 +113,7 @@ class CommandSuccessResponse(BaseModel):
99
113
  """
100
114
  Command success response model for /cmd endpoint.
101
115
  """
116
+
102
117
  result: Dict[str, Any] = Field(..., description="Command execution result")
103
118
 
104
119
 
@@ -106,113 +121,124 @@ class CommandErrorResponse(BaseModel):
106
121
  """
107
122
  Command error response model for /cmd endpoint.
108
123
  """
124
+
109
125
  error: JsonRpcError = Field(..., description="Error information")
110
126
 
111
127
 
112
128
  class APIToolDescription:
113
129
  """
114
130
  Генератор описаний для инструментов API на основе метаданных команд.
115
-
131
+
116
132
  Класс предоставляет функциональность для создания подробных и понятных
117
133
  описаний инструментов API, которые помогают пользователям сразу понять
118
134
  как использовать API.
119
135
  """
120
-
136
+
121
137
  @classmethod
122
138
  def generate_tool_description(cls, name: str, registry) -> Dict[str, Any]:
123
139
  """
124
140
  Генерирует подробное описание инструмента API на основе имени и реестра команд.
125
-
141
+
126
142
  Args:
127
143
  name: Имя инструмента API
128
144
  registry: Реестр команд
129
-
145
+
130
146
  Returns:
131
147
  Словарь с полным описанием инструмента
132
148
  """
133
149
  # Получаем все метаданные из реестра команд
134
150
  all_metadata = registry.get_all_metadata()
135
-
151
+
136
152
  # Базовое описание инструмента
137
153
  description = {
138
154
  "name": name,
139
155
  "description": f"Выполняет команды через JSON-RPC протокол на сервере проекта.",
140
156
  "supported_commands": {},
141
- "examples": []
157
+ "examples": [],
142
158
  }
143
-
159
+
144
160
  # Добавляем информацию о поддерживаемых командах
145
161
  for cmd_name, metadata in all_metadata.items():
146
162
  command_info = {
147
163
  "summary": metadata["summary"],
148
164
  "description": metadata["description"],
149
165
  "params": {},
150
- "required_params": []
166
+ "required_params": [],
151
167
  }
152
-
168
+
153
169
  # Добавляем информацию о параметрах
154
170
  for param_name, param_info in metadata["params"].items():
155
171
  param_type = param_info.get("type", "any").replace("typing.", "")
156
-
172
+
157
173
  # Определяем тип параметра для документации
158
174
  simple_type = cls._simplify_type(param_type)
159
-
175
+
160
176
  command_info["params"][param_name] = {
161
177
  "type": simple_type,
162
- "description": cls._extract_param_description(metadata["description"], param_name),
163
- "required": param_info.get("required", False)
178
+ "description": cls._extract_param_description(
179
+ metadata["description"], param_name
180
+ ),
181
+ "required": param_info.get("required", False),
164
182
  }
165
-
183
+
166
184
  # Если параметр обязательный, добавляем его в список обязательных
167
185
  if param_info.get("required", False):
168
186
  command_info["required_params"].append(param_name)
169
-
187
+
170
188
  description["supported_commands"][cmd_name] = command_info
171
-
189
+
172
190
  # Добавляем примеры из метаданных команды
173
191
  for example in metadata.get("examples", []):
174
- description["examples"].append({
175
- "command": example.get("command", cmd_name),
176
- "params": example.get("params", {}),
177
- "description": example.get("description", f"Пример использования команды {cmd_name}")
178
- })
179
-
192
+ description["examples"].append(
193
+ {
194
+ "command": example.get("command", cmd_name),
195
+ "params": example.get("params", {}),
196
+ "description": example.get(
197
+ "description", f"Пример использования команды {cmd_name}"
198
+ ),
199
+ }
200
+ )
201
+
180
202
  return description
181
-
203
+
182
204
  @classmethod
183
205
  def generate_tool_description_text(cls, name: str, registry) -> str:
184
206
  """
185
207
  Генерирует текстовое описание инструмента API для документации.
186
-
208
+
187
209
  Args:
188
210
  name: Имя инструмента API
189
211
  registry: Реестр команд
190
-
212
+
191
213
  Returns:
192
214
  Текстовое описание инструмента в формате markdown
193
215
  """
194
216
  tool_data = cls.generate_tool_description(name, registry)
195
-
217
+
196
218
  # Формируем заголовок и базовое описание
197
219
  text = f"# Инструмент {tool_data['name']}\n\n"
198
220
  text += f"{tool_data['description']}\n\n"
199
-
221
+
200
222
  # Список доступных команд
201
223
  text += "## Доступные команды\n\n"
202
224
  for cmd_name, cmd_info in tool_data["supported_commands"].items():
203
225
  text += f"### {cmd_name}\n\n"
204
226
  text += f"{cmd_info['description']}\n\n"
205
-
227
+
206
228
  # Информация о параметрах
207
229
  if cmd_info["params"]:
208
230
  text += "#### Параметры:\n\n"
209
231
  for param_name, param_info in cmd_info["params"].items():
210
- required_mark = "**обязательный**" if param_info["required"] else "опциональный"
232
+ required_mark = (
233
+ "**обязательный**" if param_info["required"] else "опциональный"
234
+ )
211
235
  text += f"- `{param_name}` ({param_info['type']}, {required_mark}): {param_info['description']}\n"
212
236
  text += "\n"
213
-
237
+
214
238
  # Примеры использования
215
- cmd_examples = [ex for ex in tool_data["examples"] if ex["command"] == cmd_name]
239
+ cmd_examples = [
240
+ ex for ex in tool_data["examples"] if ex["command"] == cmd_name
241
+ ]
216
242
  if cmd_examples:
217
243
  text += "#### Примеры:\n\n"
218
244
  for i, example in enumerate(cmd_examples):
@@ -235,23 +261,23 @@ class APIToolDescription:
235
261
  text += ' "params": {}\n'
236
262
  text += "}\n"
237
263
  text += "```\n\n"
238
-
264
+
239
265
  return text
240
-
266
+
241
267
  @classmethod
242
268
  def _simplify_type(cls, type_str: str) -> str:
243
269
  """
244
270
  Упрощает строковое представление типа для документации.
245
-
271
+
246
272
  Args:
247
273
  type_str: Строковое представление типа
248
-
274
+
249
275
  Returns:
250
276
  Упрощенное строковое представление типа
251
277
  """
252
278
  # Удаляем префиксы из строки типа
253
279
  type_str = type_str.replace("<class '", "").replace("'>", "")
254
-
280
+
255
281
  # Преобразование стандартных типов
256
282
  if "str" in type_str:
257
283
  return "строка"
@@ -271,16 +297,16 @@ class APIToolDescription:
271
297
  return cls._simplify_type(inner_type)
272
298
  else:
273
299
  return "значение"
274
-
300
+
275
301
  @classmethod
276
302
  def _extract_param_description(cls, doc_string: str, param_name: str) -> str:
277
303
  """
278
304
  Извлекает описание параметра из строки документации.
279
-
305
+
280
306
  Args:
281
307
  doc_string: Строка документации
282
308
  param_name: Имя параметра
283
-
309
+
284
310
  Returns:
285
311
  Описание параметра или пустая строка, если описание не найдено
286
312
  """
@@ -291,13 +317,13 @@ class APIToolDescription:
291
317
  args_section = doc_string.split("Parameters:")[1].split("\n\n")[0]
292
318
  else:
293
319
  return ""
294
-
320
+
295
321
  # Ищем описание параметра
296
322
  for line in args_section.split("\n"):
297
323
  line = line.strip()
298
324
  if line.startswith(param_name + ":") or line.startswith(param_name + " :"):
299
325
  return line.split(":", 1)[1].strip()
300
-
326
+
301
327
  return ""
302
328
 
303
329
 
@@ -19,31 +19,39 @@ logger = logging.getLogger(__name__)
19
19
  class ToolIntegration:
20
20
  """
21
21
  Класс для интеграции метаданных команд с внешними инструментами API.
22
-
22
+
23
23
  Обеспечивает генерацию описаний инструментов API для различных систем
24
24
  на основе метаданных команд микросервиса.
25
25
  """
26
-
26
+
27
27
  @classmethod
28
- def generate_tool_schema(cls, tool_name: str, registry: CommandRegistry,
29
- description: Optional[str] = None) -> Dict[str, Any]:
28
+ def generate_tool_schema(
29
+ cls,
30
+ tool_name: str,
31
+ registry: CommandRegistry,
32
+ description: Optional[str] = None,
33
+ ) -> Dict[str, Any]:
30
34
  """
31
35
  Генерирует схему инструмента API для использования в OpenAPI и других системах.
32
-
36
+
33
37
  Args:
34
38
  tool_name: Имя инструмента API
35
39
  registry: Реестр команд
36
40
  description: Дополнительное описание инструмента (опционально)
37
-
41
+
38
42
  Returns:
39
43
  Словарь с описанием инструмента в формате OpenAPI
40
44
  """
41
45
  # Получаем базовое описание инструмента
42
- base_description = APIToolDescription.generate_tool_description(tool_name, registry)
43
-
46
+ base_description = APIToolDescription.generate_tool_description(
47
+ tool_name, registry
48
+ )
49
+
44
50
  # Получаем типы параметров
45
- parameter_types = cls._extract_parameter_types(base_description["supported_commands"])
46
-
51
+ parameter_types = cls._extract_parameter_types(
52
+ base_description["supported_commands"]
53
+ )
54
+
47
55
  # Формируем схему инструмента
48
56
  schema = {
49
57
  "name": tool_name,
@@ -53,100 +61,105 @@ class ToolIntegration:
53
61
  "command": {
54
62
  "description": "Команда для выполнения",
55
63
  "type": "string",
56
- "enum": list(base_description["supported_commands"].keys())
64
+ "enum": list(base_description["supported_commands"].keys()),
57
65
  },
58
66
  "params": {
59
67
  "description": "Параметры команды",
60
68
  "type": "object",
61
69
  "additionalProperties": True,
62
- "properties": parameter_types
63
- }
70
+ "properties": parameter_types,
71
+ },
64
72
  },
65
73
  "required": ["command"],
66
- "type": "object"
67
- }
74
+ "type": "object",
75
+ },
68
76
  }
69
-
77
+
70
78
  return schema
71
-
79
+
72
80
  @classmethod
73
- def generate_tool_documentation(cls, tool_name: str, registry: CommandRegistry,
74
- format: str = "markdown") -> str:
81
+ def generate_tool_documentation(
82
+ cls, tool_name: str, registry: CommandRegistry, format: str = "markdown"
83
+ ) -> str:
75
84
  """
76
85
  Генерирует документацию по инструменту API в заданном формате.
77
-
86
+
78
87
  Args:
79
88
  tool_name: Имя инструмента API
80
89
  registry: Реестр команд
81
90
  format: Формат документации (markdown, html)
82
-
91
+
83
92
  Returns:
84
93
  Строка с документацией в заданном формате
85
94
  """
86
95
  if format.lower() == "markdown":
87
- return APIToolDescription.generate_tool_description_text(tool_name, registry)
96
+ return APIToolDescription.generate_tool_description_text(
97
+ tool_name, registry
98
+ )
88
99
  elif format.lower() == "html":
89
- # Преобразуем markdown в HTML (в реальном проекте здесь будет
100
+ # Преобразуем markdown в HTML (в реальном проекте здесь будет
90
101
  # использоваться библиотека для конвертации markdown в HTML)
91
- markdown = APIToolDescription.generate_tool_description_text(tool_name, registry)
102
+ markdown = APIToolDescription.generate_tool_description_text(
103
+ tool_name, registry
104
+ )
92
105
  # Простая конвертация для примера
93
- body = markdown.replace('#', '<h1>').replace('\n\n', '</p><p>')
106
+ body = markdown.replace("#", "<h1>").replace("\n\n", "</p><p>")
94
107
  html = f"<html><body>{body}</body></html>"
95
108
  return html
96
109
  else:
97
110
  # По умолчанию возвращаем markdown
98
- return APIToolDescription.generate_tool_description_text(tool_name, registry)
99
-
111
+ return APIToolDescription.generate_tool_description_text(
112
+ tool_name, registry
113
+ )
114
+
100
115
  @classmethod
101
- def register_external_tools(cls, registry: CommandRegistry, tool_names: List[str]) -> Dict[str, Dict[str, Any]]:
116
+ def register_external_tools(
117
+ cls, registry: CommandRegistry, tool_names: List[str]
118
+ ) -> Dict[str, Dict[str, Any]]:
102
119
  """
103
120
  Регистрирует инструменты API во внешних системах.
104
-
121
+
105
122
  Args:
106
123
  registry: Реестр команд
107
124
  tool_names: Список имен инструментов API для регистрации
108
-
125
+
109
126
  Returns:
110
127
  Словарь с результатами регистрации инструментов
111
128
  """
112
129
  results = {}
113
-
130
+
114
131
  for tool_name in tool_names:
115
132
  try:
116
133
  # Генерируем схему инструмента
117
134
  schema = cls.generate_tool_schema(tool_name, registry)
118
-
135
+
119
136
  # Здесь будет код для регистрации инструмента во внешней системе
120
137
  # Например, отправка схемы в API регистрации инструментов
121
-
122
- results[tool_name] = {
123
- "status": "success",
124
- "schema": schema
125
- }
126
-
138
+
139
+ results[tool_name] = {"status": "success", "schema": schema}
140
+
127
141
  logger.info(f"Successfully registered tool: {tool_name}")
128
142
  except Exception as e:
129
143
  logger.debug(f"Error registering tool {tool_name}: {e}")
130
- results[tool_name] = {
131
- "status": "error",
132
- "error": str(e)
133
- }
134
-
144
+ results[tool_name] = {"status": "error", "error": str(e)}
145
+
135
146
  return results
136
-
147
+
137
148
  @classmethod
138
- def _extract_parameter_types(cls, commands: Dict[str, Dict[str, Any]]) -> Dict[str, Dict[str, Any]]:
149
+ def _extract_parameter_types(
150
+ cls, commands: Dict[str, Dict[str, Any]]
151
+ ) -> Dict[str, Dict[str, Any]]:
139
152
  """
140
153
  Извлекает типы параметров из описания команд для формирования схемы.
141
-
154
+
142
155
  Args:
143
156
  commands: Словарь с описанием команд
144
-
157
+
145
158
  Returns:
146
159
  Словарь с типами параметров для схемы OpenAPI
147
160
  """
148
161
  parameter_types = {}
149
-
162
+
150
163
  # Формируем словарь типов для всех параметров всех команд
151
164
  for cmd_name, cmd_info in commands.items():
152
165
  params = cmd_info.get("params", {})
@@ -154,7 +167,7 @@ class ToolIntegration:
154
167
  continue
155
168
  for param_name, param_info in params.items():
156
169
  param_type = param_info.get("type", "значение")
157
-
170
+
158
171
  # Преобразуем русские типы в типы JSON Schema
159
172
  if param_type == "строка":
160
173
  json_type = "string"
@@ -170,58 +183,65 @@ class ToolIntegration:
170
183
  json_type = "object"
171
184
  else:
172
185
  json_type = "string"
173
-
186
+
174
187
  # Добавляем тип в общий словарь
175
188
  parameter_types[param_name] = {
176
189
  "type": json_type,
177
- "description": param_info.get("description", "")
190
+ "description": param_info.get("description", ""),
178
191
  }
179
-
192
+
180
193
  return parameter_types
181
194
 
182
195
 
183
196
  def generate_tool_help(tool_name: str, registry: CommandRegistry) -> str:
184
197
  """
185
198
  Генерирует справочную информацию по инструменту API.
186
-
199
+
187
200
  Args:
188
201
  tool_name: Имя инструмента API
189
202
  registry: Реестр команд
190
-
203
+
191
204
  Returns:
192
205
  Строка с описанием инструмента и доступных команд
193
206
  """
194
207
  # Получаем метаданные всех команд
195
208
  all_metadata = registry.get_all_metadata()
196
-
209
+
197
210
  # Формируем текст справки
198
211
  help_text = f"# Инструмент {tool_name}\n\n"
199
212
  help_text += "Позволяет выполнять команды через JSON-RPC протокол.\n\n"
200
213
  help_text += "## Доступные команды:\n\n"
201
-
214
+
202
215
  # Добавляем информацию о каждой команде
203
216
  for cmd_name, metadata in all_metadata.items():
204
217
  help_text += f"### {cmd_name}\n"
205
218
  help_text += f"{metadata['summary']}\n\n"
206
-
219
+
207
220
  # Добавляем информацию о параметрах команды
208
221
  if metadata["params"]:
209
222
  help_text += "Параметры:\n"
210
223
  for param_name, param_info in metadata["params"].items():
211
- required = "обязательный" if param_info.get("required", False) else "опциональный"
224
+ required = (
225
+ "обязательный"
226
+ if param_info.get("required", False)
227
+ else "опциональный"
228
+ )
212
229
  help_text += f"- {param_name}: {required}\n"
213
230
  help_text += "\n"
214
-
231
+
215
232
  # Добавляем пример использования команды
216
233
  if metadata.get("examples"):
217
234
  example = metadata["examples"][0]
218
235
  help_text += "Пример:\n"
219
236
  help_text += "```json\n"
220
237
  help_text += json.dumps(
221
- {"command": example.get("command", cmd_name), "params": example.get("params", {})},
238
+ {
239
+ "command": example.get("command", cmd_name),
240
+ "params": example.get("params", {}),
241
+ },
222
242
  indent=2,
223
- ensure_ascii=False
243
+ ensure_ascii=False,
224
244
  )
225
245
  help_text += "\n```\n\n"
226
-
227
- return help_text
246
+
247
+ return help_text