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.
- mcp_proxy_adapter/__init__.py +47 -0
- mcp_proxy_adapter/__main__.py +13 -0
- mcp_proxy_adapter/api/__init__.py +0 -0
- mcp_proxy_adapter/api/app.py +66 -0
- mcp_proxy_adapter/api/core/__init__.py +18 -0
- mcp_proxy_adapter/api/core/app_factory.py +355 -0
- mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
- mcp_proxy_adapter/api/core/registration_context.py +356 -0
- mcp_proxy_adapter/api/core/registration_manager.py +266 -0
- mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
- mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
- mcp_proxy_adapter/api/handlers.py +181 -0
- mcp_proxy_adapter/api/middleware/__init__.py +21 -0
- mcp_proxy_adapter/api/middleware/base.py +54 -0
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
- mcp_proxy_adapter/api/middleware/factory.py +147 -0
- mcp_proxy_adapter/api/middleware/logging.py +31 -0
- mcp_proxy_adapter/api/middleware/performance.py +51 -0
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
- mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
- mcp_proxy_adapter/api/openapi/__init__.py +21 -0
- mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
- mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
- mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
- mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
- mcp_proxy_adapter/api/schemas.py +270 -0
- mcp_proxy_adapter/api/tool_integration.py +131 -0
- mcp_proxy_adapter/api/tools.py +163 -0
- mcp_proxy_adapter/cli/__init__.py +12 -0
- mcp_proxy_adapter/cli/commands/__init__.py +15 -0
- mcp_proxy_adapter/cli/commands/client.py +100 -0
- mcp_proxy_adapter/cli/commands/config_generate.py +35 -0
- mcp_proxy_adapter/cli/commands/config_validate.py +74 -0
- mcp_proxy_adapter/cli/commands/generate.py +259 -0
- mcp_proxy_adapter/cli/commands/server.py +174 -0
- mcp_proxy_adapter/cli/commands/sets.py +128 -0
- mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
- mcp_proxy_adapter/cli/examples/__init__.py +8 -0
- mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
- mcp_proxy_adapter/cli/examples/https_token.py +96 -0
- mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
- mcp_proxy_adapter/cli/main.py +63 -0
- mcp_proxy_adapter/cli/parser.py +338 -0
- mcp_proxy_adapter/cli/validators.py +231 -0
- mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
- mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
- mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
- mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
- mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
- mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
- mcp_proxy_adapter/client/proxy.py +123 -0
- mcp_proxy_adapter/commands/__init__.py +66 -0
- mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
- mcp_proxy_adapter/commands/base.py +389 -0
- mcp_proxy_adapter/commands/builtin_commands.py +30 -0
- mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
- mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
- mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
- mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
- mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
- mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
- mcp_proxy_adapter/commands/catalog_manager.py +97 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
- mcp_proxy_adapter/commands/command_registry.py +298 -0
- mcp_proxy_adapter/commands/config_command.py +102 -0
- mcp_proxy_adapter/commands/dependency_container.py +40 -0
- mcp_proxy_adapter/commands/dependency_manager.py +143 -0
- mcp_proxy_adapter/commands/echo_command.py +48 -0
- mcp_proxy_adapter/commands/health_command.py +142 -0
- mcp_proxy_adapter/commands/help_command.py +175 -0
- mcp_proxy_adapter/commands/hooks.py +172 -0
- mcp_proxy_adapter/commands/key_management_command.py +484 -0
- mcp_proxy_adapter/commands/load_command.py +123 -0
- mcp_proxy_adapter/commands/plugins_command.py +246 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
- mcp_proxy_adapter/commands/queue_commands.py +750 -0
- mcp_proxy_adapter/commands/registration_status_command.py +76 -0
- mcp_proxy_adapter/commands/registry/__init__.py +18 -0
- mcp_proxy_adapter/commands/registry/command_info.py +103 -0
- mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
- mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
- mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
- mcp_proxy_adapter/commands/reload_command.py +136 -0
- mcp_proxy_adapter/commands/result.py +157 -0
- mcp_proxy_adapter/commands/role_test_command.py +99 -0
- mcp_proxy_adapter/commands/roles_management_command.py +502 -0
- mcp_proxy_adapter/commands/security_command.py +472 -0
- mcp_proxy_adapter/commands/settings_command.py +113 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
- mcp_proxy_adapter/commands/token_management_command.py +500 -0
- mcp_proxy_adapter/commands/transport_management_command.py +129 -0
- mcp_proxy_adapter/commands/unload_command.py +92 -0
- mcp_proxy_adapter/config.py +32 -0
- mcp_proxy_adapter/core/__init__.py +8 -0
- mcp_proxy_adapter/core/app_factory.py +560 -0
- mcp_proxy_adapter/core/app_runner.py +318 -0
- mcp_proxy_adapter/core/auth_validator.py +508 -0
- mcp_proxy_adapter/core/certificate/__init__.py +20 -0
- mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
- mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
- mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/certificate/certificate_validator.py +388 -0
- mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
- mcp_proxy_adapter/core/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/client.py +608 -0
- mcp_proxy_adapter/core/client_manager.py +271 -0
- mcp_proxy_adapter/core/client_security.py +411 -0
- mcp_proxy_adapter/core/config/__init__.py +18 -0
- mcp_proxy_adapter/core/config/config.py +237 -0
- mcp_proxy_adapter/core/config/config_factory.py +22 -0
- mcp_proxy_adapter/core/config/config_loader.py +66 -0
- mcp_proxy_adapter/core/config/feature_manager.py +31 -0
- mcp_proxy_adapter/core/config/simple_config.py +116 -0
- mcp_proxy_adapter/core/config/simple_config_generator.py +100 -0
- mcp_proxy_adapter/core/config/simple_config_validator.py +380 -0
- mcp_proxy_adapter/core/config_converter.py +252 -0
- mcp_proxy_adapter/core/config_validator.py +211 -0
- mcp_proxy_adapter/core/crl_utils.py +362 -0
- mcp_proxy_adapter/core/errors.py +276 -0
- mcp_proxy_adapter/core/job_manager.py +54 -0
- mcp_proxy_adapter/core/logging.py +250 -0
- mcp_proxy_adapter/core/mtls_asgi.py +140 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/mtls_proxy.py +229 -0
- mcp_proxy_adapter/core/mtls_server.py +154 -0
- mcp_proxy_adapter/core/protocol_manager.py +232 -0
- mcp_proxy_adapter/core/proxy/__init__.py +19 -0
- mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
- mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
- mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
- mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
- mcp_proxy_adapter/core/proxy_client.py +184 -0
- mcp_proxy_adapter/core/proxy_registration.py +80 -0
- mcp_proxy_adapter/core/role_utils.py +103 -0
- mcp_proxy_adapter/core/security_adapter.py +343 -0
- mcp_proxy_adapter/core/security_factory.py +96 -0
- mcp_proxy_adapter/core/security_integration.py +342 -0
- mcp_proxy_adapter/core/server_adapter.py +251 -0
- mcp_proxy_adapter/core/server_engine.py +217 -0
- mcp_proxy_adapter/core/settings.py +260 -0
- mcp_proxy_adapter/core/signal_handler.py +107 -0
- mcp_proxy_adapter/core/ssl_utils.py +161 -0
- mcp_proxy_adapter/core/transport_manager.py +153 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
- mcp_proxy_adapter/core/utils.py +101 -0
- mcp_proxy_adapter/core/validation/__init__.py +21 -0
- mcp_proxy_adapter/core/validation/config_validator.py +219 -0
- mcp_proxy_adapter/core/validation/file_validator.py +131 -0
- mcp_proxy_adapter/core/validation/protocol_validator.py +190 -0
- mcp_proxy_adapter/core/validation/security_validator.py +140 -0
- mcp_proxy_adapter/core/validation/validation_result.py +27 -0
- mcp_proxy_adapter/custom_openapi.py +58 -0
- mcp_proxy_adapter/examples/__init__.py +16 -0
- mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
- mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
- mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
- mcp_proxy_adapter/examples/check_config.py +413 -0
- mcp_proxy_adapter/examples/client_usage_example.py +164 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/config_builder.py +234 -0
- mcp_proxy_adapter/examples/config_cli.py +282 -0
- mcp_proxy_adapter/examples/create_test_configs.py +174 -0
- mcp_proxy_adapter/examples/debug_request_state.py +130 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
- mcp_proxy_adapter/examples/demo_client.py +287 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +13 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
- mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
- mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
- mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
- mcp_proxy_adapter/examples/full_application/main.py +264 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +81 -0
- mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
- mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
- mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
- mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
- mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
- mcp_proxy_adapter/examples/generate_config.py +502 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
- mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
- mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
- mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
- mcp_proxy_adapter/examples/queue_server_example.py +85 -0
- mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
- mcp_proxy_adapter/examples/required_certificates.py +208 -0
- mcp_proxy_adapter/examples/run_example.py +77 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
- mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
- mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
- mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
- mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
- mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
- mcp_proxy_adapter/examples/security_test_client.py +72 -0
- mcp_proxy_adapter/examples/setup/__init__.py +24 -0
- mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
- mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
- mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
- mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
- mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
- mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
- mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
- mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
- mcp_proxy_adapter/examples/test_config.py +205 -0
- mcp_proxy_adapter/examples/test_config_builder.py +110 -0
- mcp_proxy_adapter/examples/test_examples.py +308 -0
- mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
- mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
- mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
- mcp_proxy_adapter/examples/universal_client.py +674 -0
- mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
- mcp_proxy_adapter/integrations/__init__.py +25 -0
- mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
- mcp_proxy_adapter/main.py +313 -0
- mcp_proxy_adapter/openapi.py +375 -0
- mcp_proxy_adapter/schemas/base_schema.json +114 -0
- mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
- mcp_proxy_adapter/schemas/roles.json +37 -0
- mcp_proxy_adapter/schemas/roles_schema.json +162 -0
- mcp_proxy_adapter/version.py +5 -0
- mcp_proxy_adapter-6.9.43.dist-info/METADATA +739 -0
- mcp_proxy_adapter-6.9.43.dist-info/RECORD +242 -0
- mcp_proxy_adapter-6.9.43.dist-info/WHEEL +5 -0
- mcp_proxy_adapter-6.9.43.dist-info/entry_points.txt +12 -0
- 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,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
|
+
|