mcp-proxy-adapter 6.9.43__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 (242) hide show
  1. mcp_proxy_adapter/__init__.py +47 -0
  2. mcp_proxy_adapter/__main__.py +13 -0
  3. mcp_proxy_adapter/api/__init__.py +0 -0
  4. mcp_proxy_adapter/api/app.py +66 -0
  5. mcp_proxy_adapter/api/core/__init__.py +18 -0
  6. mcp_proxy_adapter/api/core/app_factory.py +355 -0
  7. mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
  8. mcp_proxy_adapter/api/core/registration_context.py +356 -0
  9. mcp_proxy_adapter/api/core/registration_manager.py +266 -0
  10. mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
  11. mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
  12. mcp_proxy_adapter/api/handlers.py +181 -0
  13. mcp_proxy_adapter/api/middleware/__init__.py +21 -0
  14. mcp_proxy_adapter/api/middleware/base.py +54 -0
  15. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
  16. mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
  17. mcp_proxy_adapter/api/middleware/factory.py +147 -0
  18. mcp_proxy_adapter/api/middleware/logging.py +31 -0
  19. mcp_proxy_adapter/api/middleware/performance.py +51 -0
  20. mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
  21. mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
  22. mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
  23. mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
  24. mcp_proxy_adapter/api/openapi/__init__.py +21 -0
  25. mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
  26. mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
  27. mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
  28. mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
  29. mcp_proxy_adapter/api/schemas.py +270 -0
  30. mcp_proxy_adapter/api/tool_integration.py +131 -0
  31. mcp_proxy_adapter/api/tools.py +163 -0
  32. mcp_proxy_adapter/cli/__init__.py +12 -0
  33. mcp_proxy_adapter/cli/commands/__init__.py +15 -0
  34. mcp_proxy_adapter/cli/commands/client.py +100 -0
  35. mcp_proxy_adapter/cli/commands/config_generate.py +35 -0
  36. mcp_proxy_adapter/cli/commands/config_validate.py +74 -0
  37. mcp_proxy_adapter/cli/commands/generate.py +259 -0
  38. mcp_proxy_adapter/cli/commands/server.py +174 -0
  39. mcp_proxy_adapter/cli/commands/sets.py +128 -0
  40. mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
  41. mcp_proxy_adapter/cli/examples/__init__.py +8 -0
  42. mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
  43. mcp_proxy_adapter/cli/examples/https_token.py +96 -0
  44. mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
  45. mcp_proxy_adapter/cli/main.py +63 -0
  46. mcp_proxy_adapter/cli/parser.py +338 -0
  47. mcp_proxy_adapter/cli/validators.py +231 -0
  48. mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
  49. mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
  50. mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
  51. mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
  52. mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
  53. mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
  54. mcp_proxy_adapter/client/proxy.py +123 -0
  55. mcp_proxy_adapter/commands/__init__.py +66 -0
  56. mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
  57. mcp_proxy_adapter/commands/base.py +389 -0
  58. mcp_proxy_adapter/commands/builtin_commands.py +30 -0
  59. mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
  60. mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
  61. mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
  62. mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
  63. mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
  64. mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
  65. mcp_proxy_adapter/commands/catalog_manager.py +97 -0
  66. mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
  67. mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
  68. mcp_proxy_adapter/commands/command_registry.py +298 -0
  69. mcp_proxy_adapter/commands/config_command.py +102 -0
  70. mcp_proxy_adapter/commands/dependency_container.py +40 -0
  71. mcp_proxy_adapter/commands/dependency_manager.py +143 -0
  72. mcp_proxy_adapter/commands/echo_command.py +48 -0
  73. mcp_proxy_adapter/commands/health_command.py +142 -0
  74. mcp_proxy_adapter/commands/help_command.py +175 -0
  75. mcp_proxy_adapter/commands/hooks.py +172 -0
  76. mcp_proxy_adapter/commands/key_management_command.py +484 -0
  77. mcp_proxy_adapter/commands/load_command.py +123 -0
  78. mcp_proxy_adapter/commands/plugins_command.py +246 -0
  79. mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
  80. mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
  81. mcp_proxy_adapter/commands/queue_commands.py +750 -0
  82. mcp_proxy_adapter/commands/registration_status_command.py +76 -0
  83. mcp_proxy_adapter/commands/registry/__init__.py +18 -0
  84. mcp_proxy_adapter/commands/registry/command_info.py +103 -0
  85. mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
  86. mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
  87. mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
  88. mcp_proxy_adapter/commands/reload_command.py +136 -0
  89. mcp_proxy_adapter/commands/result.py +157 -0
  90. mcp_proxy_adapter/commands/role_test_command.py +99 -0
  91. mcp_proxy_adapter/commands/roles_management_command.py +502 -0
  92. mcp_proxy_adapter/commands/security_command.py +472 -0
  93. mcp_proxy_adapter/commands/settings_command.py +113 -0
  94. mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
  95. mcp_proxy_adapter/commands/token_management_command.py +500 -0
  96. mcp_proxy_adapter/commands/transport_management_command.py +129 -0
  97. mcp_proxy_adapter/commands/unload_command.py +92 -0
  98. mcp_proxy_adapter/config.py +32 -0
  99. mcp_proxy_adapter/core/__init__.py +8 -0
  100. mcp_proxy_adapter/core/app_factory.py +560 -0
  101. mcp_proxy_adapter/core/app_runner.py +318 -0
  102. mcp_proxy_adapter/core/auth_validator.py +508 -0
  103. mcp_proxy_adapter/core/certificate/__init__.py +20 -0
  104. mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
  105. mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
  106. mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
  107. mcp_proxy_adapter/core/certificate/certificate_validator.py +388 -0
  108. mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
  109. mcp_proxy_adapter/core/certificate_utils.py +249 -0
  110. mcp_proxy_adapter/core/client.py +608 -0
  111. mcp_proxy_adapter/core/client_manager.py +271 -0
  112. mcp_proxy_adapter/core/client_security.py +411 -0
  113. mcp_proxy_adapter/core/config/__init__.py +18 -0
  114. mcp_proxy_adapter/core/config/config.py +237 -0
  115. mcp_proxy_adapter/core/config/config_factory.py +22 -0
  116. mcp_proxy_adapter/core/config/config_loader.py +66 -0
  117. mcp_proxy_adapter/core/config/feature_manager.py +31 -0
  118. mcp_proxy_adapter/core/config/simple_config.py +116 -0
  119. mcp_proxy_adapter/core/config/simple_config_generator.py +100 -0
  120. mcp_proxy_adapter/core/config/simple_config_validator.py +380 -0
  121. mcp_proxy_adapter/core/config_converter.py +252 -0
  122. mcp_proxy_adapter/core/config_validator.py +211 -0
  123. mcp_proxy_adapter/core/crl_utils.py +362 -0
  124. mcp_proxy_adapter/core/errors.py +276 -0
  125. mcp_proxy_adapter/core/job_manager.py +54 -0
  126. mcp_proxy_adapter/core/logging.py +250 -0
  127. mcp_proxy_adapter/core/mtls_asgi.py +140 -0
  128. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  129. mcp_proxy_adapter/core/mtls_proxy.py +229 -0
  130. mcp_proxy_adapter/core/mtls_server.py +154 -0
  131. mcp_proxy_adapter/core/protocol_manager.py +232 -0
  132. mcp_proxy_adapter/core/proxy/__init__.py +19 -0
  133. mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
  134. mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
  135. mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
  136. mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
  137. mcp_proxy_adapter/core/proxy_client.py +184 -0
  138. mcp_proxy_adapter/core/proxy_registration.py +80 -0
  139. mcp_proxy_adapter/core/role_utils.py +103 -0
  140. mcp_proxy_adapter/core/security_adapter.py +343 -0
  141. mcp_proxy_adapter/core/security_factory.py +96 -0
  142. mcp_proxy_adapter/core/security_integration.py +342 -0
  143. mcp_proxy_adapter/core/server_adapter.py +251 -0
  144. mcp_proxy_adapter/core/server_engine.py +217 -0
  145. mcp_proxy_adapter/core/settings.py +260 -0
  146. mcp_proxy_adapter/core/signal_handler.py +107 -0
  147. mcp_proxy_adapter/core/ssl_utils.py +161 -0
  148. mcp_proxy_adapter/core/transport_manager.py +153 -0
  149. mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
  150. mcp_proxy_adapter/core/utils.py +101 -0
  151. mcp_proxy_adapter/core/validation/__init__.py +21 -0
  152. mcp_proxy_adapter/core/validation/config_validator.py +219 -0
  153. mcp_proxy_adapter/core/validation/file_validator.py +131 -0
  154. mcp_proxy_adapter/core/validation/protocol_validator.py +190 -0
  155. mcp_proxy_adapter/core/validation/security_validator.py +140 -0
  156. mcp_proxy_adapter/core/validation/validation_result.py +27 -0
  157. mcp_proxy_adapter/custom_openapi.py +58 -0
  158. mcp_proxy_adapter/examples/__init__.py +16 -0
  159. mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
  160. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  161. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  162. mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
  163. mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
  164. mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
  165. mcp_proxy_adapter/examples/check_config.py +413 -0
  166. mcp_proxy_adapter/examples/client_usage_example.py +164 -0
  167. mcp_proxy_adapter/examples/commands/__init__.py +5 -0
  168. mcp_proxy_adapter/examples/config_builder.py +234 -0
  169. mcp_proxy_adapter/examples/config_cli.py +282 -0
  170. mcp_proxy_adapter/examples/create_test_configs.py +174 -0
  171. mcp_proxy_adapter/examples/debug_request_state.py +130 -0
  172. mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
  173. mcp_proxy_adapter/examples/demo_client.py +287 -0
  174. mcp_proxy_adapter/examples/full_application/__init__.py +13 -0
  175. mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
  176. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
  177. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
  178. mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
  179. mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
  180. mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
  181. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
  182. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
  183. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
  184. mcp_proxy_adapter/examples/full_application/main.py +264 -0
  185. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +81 -0
  186. mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
  187. mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
  188. mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
  189. mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
  190. mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
  191. mcp_proxy_adapter/examples/generate_config.py +502 -0
  192. mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
  193. mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
  194. mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
  195. mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
  196. mcp_proxy_adapter/examples/queue_server_example.py +85 -0
  197. mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
  198. mcp_proxy_adapter/examples/required_certificates.py +208 -0
  199. mcp_proxy_adapter/examples/run_example.py +77 -0
  200. mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
  201. mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
  202. mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
  203. mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
  204. mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
  205. mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
  206. mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
  207. mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
  208. mcp_proxy_adapter/examples/security_test_client.py +72 -0
  209. mcp_proxy_adapter/examples/setup/__init__.py +24 -0
  210. mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
  211. mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
  212. mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
  213. mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
  214. mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
  215. mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
  216. mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
  217. mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
  218. mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
  219. mcp_proxy_adapter/examples/test_config.py +205 -0
  220. mcp_proxy_adapter/examples/test_config_builder.py +110 -0
  221. mcp_proxy_adapter/examples/test_examples.py +308 -0
  222. mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
  223. mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
  224. mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
  225. mcp_proxy_adapter/examples/universal_client.py +674 -0
  226. mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
  227. mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
  228. mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
  229. mcp_proxy_adapter/integrations/__init__.py +25 -0
  230. mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
  231. mcp_proxy_adapter/main.py +313 -0
  232. mcp_proxy_adapter/openapi.py +375 -0
  233. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  234. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  235. mcp_proxy_adapter/schemas/roles.json +37 -0
  236. mcp_proxy_adapter/schemas/roles_schema.json +162 -0
  237. mcp_proxy_adapter/version.py +5 -0
  238. mcp_proxy_adapter-6.9.43.dist-info/METADATA +739 -0
  239. mcp_proxy_adapter-6.9.43.dist-info/RECORD +242 -0
  240. mcp_proxy_adapter-6.9.43.dist-info/WHEEL +5 -0
  241. mcp_proxy_adapter-6.9.43.dist-info/entry_points.txt +12 -0
  242. mcp_proxy_adapter-6.9.43.dist-info/top_level.txt +1 -0
@@ -0,0 +1,270 @@
1
+ """
2
+ Module with API schema definitions.
3
+ """
4
+
5
+ from typing import Any, Dict, List, Optional, Union, Literal
6
+
7
+ from pydantic import BaseModel, Field
8
+
9
+
10
+ class ErrorResponse(BaseModel):
11
+ """
12
+ Error response model.
13
+ """
14
+
15
+ code: int = Field(..., description="Error code")
16
+ message: str = Field(..., description="Error message")
17
+ details: Optional[Dict[str, Any]] = Field(
18
+ None, description="Additional error details"
19
+ )
20
+
21
+
22
+ class ErrorWrapper(BaseModel):
23
+ """
24
+ Wrapper for error response.
25
+ """
26
+
27
+ error: ErrorResponse
28
+
29
+
30
+ class JsonRpcRequest(BaseModel):
31
+ """
32
+ JSON-RPC request model.
33
+ """
34
+
35
+ jsonrpc: Literal["2.0"] = Field("2.0", description="JSON-RPC version")
36
+ method: str = Field(..., description="Method name")
37
+ params: Optional[Union[Dict[str, Any], List[Any]]] = Field(
38
+ None, description="Method parameters"
39
+ )
40
+ id: Optional[Union[str, int]] = Field(None, description="Request ID")
41
+
42
+
43
+ class JsonRpcError(BaseModel):
44
+ """
45
+ JSON-RPC error model.
46
+ """
47
+
48
+ code: int = Field(..., description="Error code")
49
+ message: str = Field(..., description="Error message")
50
+ data: Optional[Dict[str, Any]] = Field(None, description="Additional error data")
51
+
52
+
53
+ class JsonRpcSuccessResponse(BaseModel):
54
+ """
55
+ JSON-RPC success response model.
56
+ """
57
+
58
+ jsonrpc: Literal["2.0"] = Field("2.0", description="JSON-RPC version")
59
+ result: Dict[str, Any] = Field(..., description="Method result")
60
+ id: Optional[Union[str, int]] = Field(None, description="Request ID")
61
+
62
+
63
+ class JsonRpcErrorResponse(BaseModel):
64
+ """
65
+ JSON-RPC error response model.
66
+ """
67
+
68
+ jsonrpc: Literal["2.0"] = Field("2.0", description="JSON-RPC version")
69
+ error: JsonRpcError = Field(..., description="Error information")
70
+ id: Optional[Union[str, int]] = Field(None, description="Request ID")
71
+
72
+
73
+ class CommandResponse(BaseModel):
74
+ """
75
+ Command response model.
76
+ """
77
+
78
+ success: bool = Field(..., description="Command execution success flag")
79
+ data: Optional[Dict[str, Any]] = Field(None, description="Result data")
80
+ message: Optional[str] = Field(None, description="Result message")
81
+ error: Optional[ErrorResponse] = Field(None, description="Error information")
82
+
83
+
84
+ class HealthResponse(BaseModel):
85
+ """
86
+ Health response model.
87
+ """
88
+
89
+ status: str = Field(..., description="Server status")
90
+ version: str = Field(..., description="Server version")
91
+ uptime: float = Field(..., description="Server uptime in seconds")
92
+ components: Dict[str, Any] = Field(..., description="Components health")
93
+
94
+
95
+ class CommandListResponse(BaseModel):
96
+ """
97
+ Command list response model.
98
+ """
99
+
100
+ commands: Dict[str, Dict[str, Any]] = Field(..., description="Available commands")
101
+
102
+
103
+ class CommandRequest(BaseModel):
104
+ """
105
+ Command request model for /cmd endpoint.
106
+ """
107
+
108
+ command: str = Field(..., description="Command name to execute")
109
+ params: Optional[Dict[str, Any]] = Field({}, description="Command parameters")
110
+
111
+
112
+ class CommandSuccessResponse(BaseModel):
113
+ """
114
+ Command success response model for /cmd endpoint.
115
+ """
116
+
117
+ result: Dict[str, Any] = Field(..., description="Command execution result")
118
+
119
+
120
+ class CommandErrorResponse(BaseModel):
121
+ """
122
+ Command error response model for /cmd endpoint.
123
+ """
124
+
125
+ error: JsonRpcError = Field(..., description="Error information")
126
+
127
+
128
+ class APIToolDescription:
129
+ """
130
+ Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ описаний для инструмСнтов API Π½Π° основС ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄.
131
+
132
+ Класс прСдоставляСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ для создания ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹Ρ… ΠΈ понятных
133
+ описаний инструмСнтов API, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌ сразу ΠΏΠΎΠ½ΡΡ‚ΡŒ
134
+ ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ API.
135
+ """
136
+
137
+ @classmethod
138
+ def generate_tool_description(cls, name: str, registry) -> Dict[str, Any]:
139
+ """
140
+ Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ описаниС инструмСнта API Π½Π° основС ΠΈΠΌΠ΅Π½ΠΈ ΠΈ рССстра ΠΊΠΎΠΌΠ°Π½Π΄.
141
+
142
+ Args:
143
+ name: Имя инструмСнта API
144
+ registry: РССстр ΠΊΠΎΠΌΠ°Π½Π΄
145
+
146
+ Returns:
147
+ Π‘Π»ΠΎΠ²Π°Ρ€ΡŒ с ΠΏΠΎΠ»Π½Ρ‹ΠΌ описаниСм инструмСнта
148
+ """
149
+ # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ всС ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· рССстра ΠΊΠΎΠΌΠ°Π½Π΄
150
+ all_metadata = registry.get_all_metadata()
151
+
152
+ # Π‘Π°Π·ΠΎΠ²ΠΎΠ΅ описаниС инструмСнта
153
+ description = {
154
+ "name": name,
155
+ "description": f"ВыполняСт ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Ρ‡Π΅Ρ€Π΅Π· JSON-RPC ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π½Π° сСрвСрС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.",
156
+ "supported_commands": {},
157
+ "examples": [],
158
+ }
159
+
160
+ # ДобавляСм ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ…
161
+ for cmd_name, metadata in all_metadata.items():
162
+ command_info = {
163
+ "summary": metadata["summary"],
164
+ "description": metadata["description"],
165
+ "params": {},
166
+ "required_params": [],
167
+ }
168
+
169
+ # ДобавляСм ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°Ρ…
170
+ for param_name, param_info in metadata["params"].items():
171
+ param_type = param_info.get("type", "any").replace("typing.", "")
172
+
173
+ # ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅ΠΌ Ρ‚ΠΈΠΏ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° для Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ
174
+ simple_type = cls._simplify_type(param_type)
175
+
176
+ command_info["params"][param_name] = {
177
+ "type": simple_type,
178
+ "description": cls._extract_param_description(
179
+ metadata["description"], param_name
180
+ ),
181
+ "required": param_info.get("required", False),
182
+ }
183
+
184
+ # Если ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ, добавляСм Π΅Π³ΠΎ Π² список ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ…
185
+ if param_info.get("required", False):
186
+ command_info["required_params"].append(param_name)
187
+
188
+ description["supported_commands"][cmd_name] = command_info
189
+
190
+ # ДобавляСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΈΠ· ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹
191
+ for example in metadata.get("examples", []):
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
+
202
+ return description
203
+
204
+ @classmethod
205
+
206
+ @classmethod
207
+ def _simplify_type(cls, type_str: str) -> str:
208
+ """
209
+ Π£ΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ строковоС прСдставлСниС Ρ‚ΠΈΠΏΠ° для Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ.
210
+
211
+ Args:
212
+ type_str: Π‘Ρ‚Ρ€ΠΎΠΊΠΎΠ²ΠΎΠ΅ прСдставлСниС Ρ‚ΠΈΠΏΠ°
213
+
214
+ Returns:
215
+ Π£ΠΏΡ€ΠΎΡ‰Π΅Π½Π½ΠΎΠ΅ строковоС прСдставлСниС Ρ‚ΠΈΠΏΠ°
216
+ """
217
+ # УдаляСм прСфиксы ΠΈΠ· строки Ρ‚ΠΈΠΏΠ°
218
+ type_str = type_str.replace("<class '", "").replace("'>", "")
219
+
220
+ # ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ стандартных Ρ‚ΠΈΠΏΠΎΠ²
221
+ if "str" in type_str:
222
+ return "строка"
223
+ elif "int" in type_str:
224
+ return "Ρ†Π΅Π»ΠΎΠ΅ число"
225
+ elif "float" in type_str:
226
+ return "число"
227
+ elif "bool" in type_str:
228
+ return "логичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅"
229
+ elif "List" in type_str or "list" in type_str:
230
+ return "список"
231
+ elif "Dict" in type_str or "dict" in type_str:
232
+ return "ΠΎΠ±ΡŠΠ΅ΠΊΡ‚"
233
+ elif "Optional" in type_str:
234
+ # ИзвлСкаСм Ρ‚ΠΈΠΏ ΠΈΠ· Optional[X]
235
+ inner_type = type_str.split("[")[1].split("]")[0]
236
+ return cls._simplify_type(inner_type)
237
+ else:
238
+ return "Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅"
239
+
240
+ @classmethod
241
+ def _extract_param_description(cls, doc_string: str, param_name: str) -> str:
242
+ """
243
+ Π˜Π·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ описаниС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΈΠ· строки Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ.
244
+
245
+ Args:
246
+ doc_string: Π‘Ρ‚Ρ€ΠΎΠΊΠ° Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ
247
+ param_name: Имя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°
248
+
249
+ Returns:
250
+ ОписаниС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΈΠ»ΠΈ пустая строка, Ссли описаниС Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ΠΎ
251
+ """
252
+ # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π΅ΡΡ‚ΡŒ Π»ΠΈ Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ сСкция Args ΠΈΠ»ΠΈ Parameters
253
+ if "Args:" in doc_string:
254
+ args_section = doc_string.split("Args:")[1].split("\n\n")[0]
255
+ elif "Parameters:" in doc_string:
256
+ args_section = doc_string.split("Parameters:")[1].split("\n\n")[0]
257
+ else:
258
+ return ""
259
+
260
+ # Π˜Ρ‰Π΅ΠΌ описаниС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°
261
+ for line in args_section.split("\n"):
262
+ line = line.strip()
263
+ if line.startswith(param_name + ":") or line.startswith(param_name + " :"):
264
+ return line.split(":", 1)[1].strip()
265
+
266
+ return ""
267
+
268
+
269
+ # Create dictionary mapping command names to their schemas
270
+ command_schemas: Dict[str, Dict[str, Any]] = {}
@@ -0,0 +1,131 @@
1
+ """
2
+ ΠœΠΎΠ΄ΡƒΠ»ΡŒ для ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄ с внСшними API инструмСнтами.
3
+
4
+ Π­Ρ‚ΠΎΡ‚ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ обСспСчиваСт ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄ микросСрвиса
5
+ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹, понятныС для Π²Π½Π΅ΡˆΠ½ΠΈΡ… систСм, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ OpenAPI, JSON-RPC,
6
+ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… API интСрфСйсов.
7
+ """
8
+
9
+ import json
10
+ import logging
11
+
12
+ from mcp_proxy_adapter.api.schemas import APIToolDescription
13
+ from mcp_proxy_adapter.commands.command_registry import CommandRegistry
14
+
15
+ from mcp_proxy_adapter.core.logging import get_global_logger
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class ToolIntegration:
20
+ """
21
+ Класс для ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄ с внСшними инструмСнтами API.
22
+
23
+ ΠžΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΡŽ описаний инструмСнтов API для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… систСм
24
+ Π½Π° основС ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄ микросСрвиса.
25
+ """
26
+
27
+ @classmethod
28
+ def generate_tool_schema(
29
+ cls,
30
+ tool_name: str,
31
+ registry: CommandRegistry,
32
+ description: Optional[str] = None,
33
+ ) -> Dict[str, Any]:
34
+ """
35
+ Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ схСму инструмСнта API для использования Π² OpenAPI ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… систСмах.
36
+
37
+ Args:
38
+ tool_name: Имя инструмСнта API
39
+ registry: РССстр ΠΊΠΎΠΌΠ°Π½Π΄
40
+ description: Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ описаниС инструмСнта (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ)
41
+
42
+ Returns:
43
+ Π‘Π»ΠΎΠ²Π°Ρ€ΡŒ с описаниСм инструмСнта Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ OpenAPI
44
+ """
45
+ # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π±Π°Π·ΠΎΠ²ΠΎΠ΅ описаниС инструмСнта
46
+ base_description = APIToolDescription.generate_tool_description(
47
+ tool_name, registry
48
+ )
49
+
50
+ # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ‚ΠΈΠΏΡ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²
51
+ parameter_types = cls._extract_parameter_types(
52
+ base_description["supported_commands"]
53
+ )
54
+
55
+ # Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ схСму инструмСнта
56
+ schema = {
57
+ "name": tool_name,
58
+ "description": description or base_description["description"],
59
+ "parameters": {
60
+ "properties": {
61
+ "command": {
62
+ "description": "Команда для выполнСния",
63
+ "type": "string",
64
+ "enum": list(base_description["supported_commands"].keys()),
65
+ },
66
+ "params": {
67
+ "description": "ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹",
68
+ "type": "object",
69
+ "additionalProperties": True,
70
+ "properties": parameter_types,
71
+ },
72
+ },
73
+ "required": ["command"],
74
+ "type": "object",
75
+ },
76
+ }
77
+
78
+ return schema
79
+
80
+ @classmethod
81
+
82
+ @classmethod
83
+
84
+ @classmethod
85
+ def _extract_parameter_types(
86
+ cls, commands: Dict[str, Dict[str, Any]]
87
+ ) -> Dict[str, Dict[str, Any]]:
88
+ """
89
+ Π˜Π·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ Ρ‚ΠΈΠΏΡ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΈΠ· описания ΠΊΠΎΠΌΠ°Π½Π΄ для формирования схСмы.
90
+
91
+ Args:
92
+ commands: Π‘Π»ΠΎΠ²Π°Ρ€ΡŒ с описаниСм ΠΊΠΎΠΌΠ°Π½Π΄
93
+
94
+ Returns:
95
+ Π‘Π»ΠΎΠ²Π°Ρ€ΡŒ с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² для схСмы OpenAPI
96
+ """
97
+ parameter_types = {}
98
+
99
+ # Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Ρ‚ΠΈΠΏΠΎΠ² для всСх ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² всСх ΠΊΠΎΠΌΠ°Π½Π΄
100
+ for cmd_name, cmd_info in commands.items():
101
+ params = cmd_info.get("params", {})
102
+ if params is None:
103
+ continue
104
+ for param_name, param_info in params.items():
105
+ param_type = param_info.get("type", "Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅")
106
+
107
+ # ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ русскиС Ρ‚ΠΈΠΏΡ‹ Π² Ρ‚ΠΈΠΏΡ‹ JSON Schema
108
+ if param_type == "строка":
109
+ json_type = "string"
110
+ elif param_type == "Ρ†Π΅Π»ΠΎΠ΅ число":
111
+ json_type = "integer"
112
+ elif param_type == "число":
113
+ json_type = "number"
114
+ elif param_type == "логичСскоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅":
115
+ json_type = "boolean"
116
+ elif param_type == "список":
117
+ json_type = "array"
118
+ elif param_type == "ΠΎΠ±ΡŠΠ΅ΠΊΡ‚":
119
+ json_type = "object"
120
+ else:
121
+ json_type = "string"
122
+
123
+ # ДобавляСм Ρ‚ΠΈΠΏ Π² ΠΎΠ±Ρ‰ΠΈΠΉ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ
124
+ parameter_types[param_name] = {
125
+ "type": json_type,
126
+ "description": param_info.get("description", ""),
127
+ }
128
+
129
+ return parameter_types
130
+
131
+
@@ -0,0 +1,163 @@
1
+ """
2
+ ΠœΠΎΠ΄ΡƒΠ»ΡŒ с Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ инструмСнтов API для Π²Π½Π΅ΡˆΠ½ΠΈΡ… систСм.
3
+
4
+ Π­Ρ‚ΠΎΡ‚ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ содСрТит классы инструмСнтов API, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ
5
+ ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ с внСшними систСмами для выполнСния ΠΊΠΎΠΌΠ°Π½Π΄ микросСрвиса.
6
+ """
7
+
8
+ from typing import Any, Dict, Optional, Union, List
9
+ import json
10
+ import logging
11
+
12
+ from mcp_proxy_adapter.api.tool_integration import ToolIntegration
13
+ from mcp_proxy_adapter.commands.command_registry import registry
14
+ from mcp_proxy_adapter.core.errors import NotFoundError, InvalidParamsError
15
+
16
+ from mcp_proxy_adapter.core.logging import get_global_logger
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class TSTCommandExecutor:
21
+ """
22
+ Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚ для выполнСния ΠΊΠΎΠΌΠ°Π½Π΄ Ρ‡Π΅Ρ€Π΅Π· JSON-RPC ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π½Π° сСрвСрС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.
23
+
24
+ Π­Ρ‚ΠΎΡ‚ класс прСдоставляСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ для выполнСния ΠΊΠΎΠΌΠ°Π½Π΄ микросСрвиса
25
+ Ρ‡Π΅Ρ€Π΅Π· внСшний интСрфСйс TST (Tool-System-Transport).
26
+ """
27
+
28
+ name = "tst_execute_command"
29
+ description = "ВыполняСт ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Ρ‡Π΅Ρ€Π΅Π· JSON-RPC ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»."
30
+
31
+ @classmethod
32
+ async def execute(
33
+ cls, command: str, params: Optional[Dict[str, Any]] = None
34
+ ) -> Dict[str, Any]:
35
+ """
36
+ ВыполняСт ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ с ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ.
37
+
38
+ Args:
39
+ command: Имя ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ для выполнСния
40
+ params: ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ)
41
+
42
+ Returns:
43
+ Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹
44
+
45
+ Raises:
46
+ NotFoundError: Если ΠΊΠΎΠΌΠ°Π½Π΄Π° Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π°
47
+ InvalidParamsError: Если ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹
48
+ """
49
+ if not params:
50
+ params = {}
51
+
52
+ get_global_logger().info(f"Executing command via TST: {command}, params: {params}")
53
+
54
+ try:
55
+ # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ сущСствованиС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹
56
+ if not registry.command_exists_with_priority(command):
57
+ raise NotFoundError(f"Команда '{command}' нС найдСна")
58
+
59
+ # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ класс ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹
60
+ command_class = registry.get_command_with_priority(command)
61
+
62
+ # ВыполняСм ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ
63
+ result = await command_class.execute(**params)
64
+
65
+ # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚
66
+ return result.to_dict()
67
+ except NotFoundError as e:
68
+ get_global_logger().error(f"Command not found: {command}")
69
+ raise
70
+ except Exception as e:
71
+ get_global_logger().exception(f"Error executing command {command}: {e}")
72
+ raise
73
+
74
+ @classmethod
75
+
76
+ @classmethod
77
+ def get_description(cls, format: str = "json") -> Union[Dict[str, Any], str]:
78
+ """
79
+ Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ»Π½ΠΎΠ΅ описаниС инструмСнта Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅.
80
+
81
+ Args:
82
+ format: Π€ΠΎΡ€ΠΌΠ°Ρ‚ описания (json, markdown, html)
83
+
84
+ Returns:
85
+ ОписаниС инструмСнта Π² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅
86
+ """
87
+ if format.lower() == "json":
88
+ # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π±Π°Π·ΠΎΠ²ΠΎΠ΅ описаниС инструмСнта
89
+ base_description = ToolIntegration.generate_tool_schema(
90
+ cls.name, registry, cls.description
91
+ )
92
+
93
+ # ДобавляСм Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ
94
+ base_description["examples"] = cls._generate_examples()
95
+ base_description["error_codes"] = cls._generate_error_codes()
96
+
97
+ return base_description
98
+ elif format.lower() in ["markdown", "text", "html"]:
99
+ return ToolIntegration.generate_tool_documentation(
100
+ cls.name, registry, format
101
+ )
102
+ else:
103
+ # По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ JSON Ρ„ΠΎΡ€ΠΌΠ°Ρ‚
104
+ return ToolIntegration.generate_tool_schema(
105
+ cls.name, registry, cls.description
106
+ )
107
+
108
+ @classmethod
109
+ def _generate_examples(cls) -> List[Dict[str, Any]]:
110
+ """
111
+ Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования инструмСнта.
112
+
113
+ Returns:
114
+ Бписок ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² использования
115
+ """
116
+ examples = []
117
+
118
+ # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ всСх ΠΊΠΎΠΌΠ°Π½Π΄
119
+ all_metadata = registry.get_all_metadata()
120
+
121
+ # ДобавляСм ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹
122
+ for cmd_name, metadata in all_metadata.items():
123
+ if metadata.get("examples"):
124
+ # Π‘Π΅Ρ€Π΅ΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ…
125
+ example = metadata["examples"][0]
126
+
127
+ # Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования инструмСнта
128
+ examples.append(
129
+ {
130
+ "command": cls.name,
131
+ "params": {
132
+ "command": example.get("command", cmd_name),
133
+ "params": example.get("params", {}),
134
+ },
135
+ "description": f"Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ {cmd_name}",
136
+ }
137
+ )
138
+
139
+ return examples
140
+
141
+ @classmethod
142
+ def _generate_error_codes(cls) -> Dict[str, str]:
143
+ """
144
+ Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΊΠΎΠ΄ΠΎΠ² ошибок.
145
+
146
+ Returns:
147
+ Π‘Π»ΠΎΠ²Π°Ρ€ΡŒ с ΠΊΠΎΠ΄Π°ΠΌΠΈ ошибок ΠΈ ΠΈΡ… описаниями
148
+ """
149
+ return {
150
+ "-32600": "НСкоррСктный запрос",
151
+ "-32601": "Команда нС найдСна",
152
+ "-32602": "НСкоррСктныС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹",
153
+ "-32603": "ВнутрСнняя ошибка",
154
+ "-32000": "Ошибка выполнСния ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹",
155
+ }
156
+
157
+
158
+ # ЭкспортируСм доступныС инструмСнты API
159
+ available_tools = {TSTCommandExecutor.name: TSTCommandExecutor}
160
+
161
+
162
+
163
+
@@ -0,0 +1,12 @@
1
+ """
2
+ MCP Proxy Adapter CLI Module
3
+
4
+ This module provides command-line interface for MCP Proxy Adapter framework.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+
10
+ from .main import main
11
+
12
+ __all__ = ['main']
@@ -0,0 +1,15 @@
1
+ """
2
+ CLI Commands Module
3
+
4
+ This module contains all CLI commands for MCP Proxy Adapter.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+
10
+ from .generate import GenerateCommand
11
+ from .testconfig import TestConfigCommand
12
+ from .server import ServerCommand
13
+ from .sets import SetsCommand
14
+
15
+ __all__ = ['GenerateCommand', 'TestConfigCommand', 'ServerCommand', 'SetsCommand']
@@ -0,0 +1,100 @@
1
+ """
2
+ MCP Client Command
3
+
4
+ Client CLI for calling health and JSON-RPC endpoints in various modes.
5
+
6
+ Author: Vasiliy Zdanovskiy
7
+ email: vasilyvz@gmail.com
8
+ """
9
+
10
+ import json
11
+ from pathlib import Path
12
+ from typing import Any, Dict, Optional
13
+
14
+ import requests
15
+ from mcp_proxy_adapter.client.proxy import ProxyClient
16
+
17
+
18
+ def _build_base_url(protocol: str, host: str, port: int) -> str:
19
+ scheme = "https" if protocol == "https" else "http"
20
+ return f"{scheme}://{host}:{port}"
21
+
22
+
23
+ def _request_kwargs(protocol: str, token_header: Optional[str], token: Optional[str],
24
+ cert: Optional[str], key: Optional[str], ca: Optional[str]) -> Dict[str, Any]:
25
+ headers: Dict[str, str] = {"Content-Type": "application/json"}
26
+ if token_header and token:
27
+ headers[token_header] = token
28
+
29
+ kwargs: Dict[str, Any] = {"headers": headers, "timeout": 10}
30
+
31
+ if protocol == "https":
32
+ if cert and key:
33
+ kwargs["cert"] = (cert, key)
34
+ # For examples we allow self-signed; if CA provided, use it, otherwise disable verification
35
+ if ca:
36
+ kwargs["verify"] = str(Path(ca))
37
+ else:
38
+ kwargs["verify"] = False
39
+
40
+ return kwargs
41
+
42
+
43
+ def client_command(args) -> int:
44
+ """Dispatch client subcommands."""
45
+ protocol = args.protocol
46
+ host = args.host
47
+ port = args.port
48
+ base = _build_base_url(protocol, host, port)
49
+ kwargs = _request_kwargs(
50
+ protocol,
51
+ getattr(args, "token_header", None),
52
+ getattr(args, "token", None),
53
+ getattr(args, "cert", None),
54
+ getattr(args, "key", None),
55
+ getattr(args, "ca", None),
56
+ )
57
+
58
+ try:
59
+ if args.client_command == "health":
60
+ resp = requests.get(f"{base}/health", **kwargs)
61
+ print(json.dumps(resp.json(), ensure_ascii=False))
62
+ return 0 if resp.ok else 1
63
+
64
+ if args.client_command == "jsonrpc":
65
+ payload: Dict[str, Any] = {
66
+ "jsonrpc": "2.0",
67
+ "method": args.method,
68
+ "params": json.loads(args.params) if args.params else {},
69
+ "id": args.id,
70
+ }
71
+ resp = requests.post(f"{base}/api/jsonrpc", data=json.dumps(payload), **kwargs)
72
+ print(json.dumps(resp.json(), ensure_ascii=False))
73
+ return 0 if resp.ok else 1
74
+
75
+ if args.client_command == "proxy-register":
76
+ pc = ProxyClient(args.proxy_url)
77
+ res = pc.register(args.name, args.url, capabilities=args.capabilities or [], metadata=None)
78
+ print(json.dumps(res, ensure_ascii=False))
79
+ return 0
80
+
81
+ if args.client_command == "proxy-unregister":
82
+ pc = ProxyClient(args.proxy_url)
83
+ res = pc.unregister(args.name)
84
+ print(json.dumps(res, ensure_ascii=False))
85
+ return 0
86
+
87
+ if args.client_command == "proxy-list":
88
+ pc = ProxyClient(args.proxy_url)
89
+ res = pc.list_servers()
90
+ print(json.dumps(res, ensure_ascii=False))
91
+ return 0
92
+
93
+ print("Available: client health|jsonrpc")
94
+ return 1
95
+
96
+ except Exception as exc: # noqa: BLE001 (keep simple CLI handling)
97
+ print(f"❌ Client error: {exc}")
98
+ return 1
99
+
100
+