mcp-proxy-adapter 2.0.1__py3-none-any.whl → 6.9.50__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.

Potentially problematic release.


This version of mcp-proxy-adapter might be problematic. Click here for more details.

Files changed (269) 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 +400 -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 +307 -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 +105 -0
  36. mcp_proxy_adapter/cli/commands/config_validate.py +94 -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 +132 -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 +481 -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 +204 -0
  119. mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
  120. mcp_proxy_adapter/core/config/simple_config_validator.py +476 -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 +205 -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 +12 -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 +311 -0
  185. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -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 +311 -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.50.dist-info/METADATA +1088 -0
  239. mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
  240. {mcp_proxy_adapter-2.0.1.dist-info → mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
  241. mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
  242. mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
  243. adapters/__init__.py +0 -16
  244. analyzers/__init__.py +0 -14
  245. analyzers/docstring_analyzer.py +0 -199
  246. analyzers/type_analyzer.py +0 -151
  247. cli/__init__.py +0 -12
  248. cli/__main__.py +0 -79
  249. cli/command_runner.py +0 -233
  250. dispatchers/__init__.py +0 -14
  251. dispatchers/base_dispatcher.py +0 -85
  252. dispatchers/json_rpc_dispatcher.py +0 -198
  253. generators/__init__.py +0 -14
  254. generators/endpoint_generator.py +0 -172
  255. generators/openapi_generator.py +0 -254
  256. generators/rest_api_generator.py +0 -207
  257. mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
  258. mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
  259. mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
  260. mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
  261. openapi_schema/__init__.py +0 -38
  262. openapi_schema/command_registry.py +0 -312
  263. openapi_schema/rest_schema.py +0 -510
  264. openapi_schema/rpc_generator.py +0 -307
  265. openapi_schema/rpc_schema.py +0 -416
  266. validators/__init__.py +0 -14
  267. validators/base_validator.py +0 -23
  268. validators/docstring_validator.py +0 -75
  269. validators/metadata_validator.py +0 -76
@@ -0,0 +1,500 @@
1
+ """
2
+ Token Management Commands
3
+
4
+ This module provides commands for managing JWT and API tokens:
5
+ - Token creation
6
+ - Token validation
7
+ - Token revocation
8
+ - Token listing
9
+ - Token refresh
10
+
11
+ Author: MCP Proxy Adapter Team
12
+ Version: 1.0.0
13
+ """
14
+
15
+ import json
16
+ import logging
17
+ import time
18
+ import uuid
19
+ from pathlib import Path
20
+ from typing import Dict, List, Any, Optional, Union
21
+
22
+ from .base import Command
23
+ from .result import SuccessResult, ErrorResult, CommandResult
24
+ from ..core.auth_validator import AuthValidator
25
+
26
+
27
+ from mcp_proxy_adapter.core.logging import get_global_logger
28
+ class TokenManagementCommand(Command):
29
+ """
30
+ Token management commands.
31
+
32
+ Provides commands for creating, validating, revoking, listing, and refreshing tokens.
33
+ Supports both JWT and API tokens.
34
+ """
35
+
36
+ def __init__(self):
37
+ """Initialize token management command."""
38
+ super().__init__()
39
+ self.auth_validator = AuthValidator()
40
+ self.logger = logging.getLogger(__name__)
41
+
42
+ # Load configuration
43
+ from ...config import config
44
+
45
+ self.token_config = config.get("ssl", {}).get("token_auth", {})
46
+ self.tokens_file = self.token_config.get("tokens_file", "tokens.json")
47
+ self.token_expiry = self.token_config.get("token_expiry", 3600)
48
+ self.jwt_secret = self.token_config.get("jwt_secret", "")
49
+ self.jwt_algorithm = self.token_config.get("jwt_algorithm", "HS256")
50
+
51
+ async def execute(self, **kwargs) -> CommandResult:
52
+ """
53
+ Execute token management command.
54
+
55
+ Args:
56
+ **kwargs: Command parameters containing:
57
+ - method: Command method (token_create, token_validate, token_revoke, token_list, token_refresh)
58
+ - token_type: Type of token for creation (jwt/api)
59
+ - token_data: Token data for creation
60
+ - token: Token string for validation/revocation/refresh
61
+ - active_only: Boolean for token listing
62
+
63
+ Returns:
64
+ CommandResult with operation result
65
+ """
66
+ try:
67
+ method = kwargs.get("method")
68
+
69
+ if method == "token_create":
70
+ token_type = kwargs.get("token_type", "api")
71
+ token_data = kwargs.get("token_data", {})
72
+ return await self.token_create(token_type, token_data)
73
+ elif method == "token_validate":
74
+ token = kwargs.get("token")
75
+ token_type = kwargs.get("token_type", "auto")
76
+ return await self.token_validate(token, token_type)
77
+ elif method == "token_revoke":
78
+ token = kwargs.get("token")
79
+ return await self.token_revoke(token)
80
+ elif method == "token_list":
81
+ active_only = kwargs.get("active_only", True)
82
+ return await self.token_list(active_only)
83
+ elif method == "token_refresh":
84
+ token = kwargs.get("token")
85
+ return await self.token_refresh(token)
86
+ else:
87
+ return ErrorResult(message=f"Unknown method: {method}", code=-32601)
88
+
89
+ except Exception as e:
90
+ self.get_global_logger().error(f"Token management command execution error: {e}")
91
+ return ErrorResult(
92
+ message=f"Token management command failed: {str(e)}", code=-32603
93
+ )
94
+
95
+ async def token_create(
96
+ self, token_type: str, token_data: Dict[str, Any]
97
+ ) -> Union[SuccessResult, ErrorResult]:
98
+ """
99
+ Create a new token.
100
+
101
+ Args:
102
+ token_type: Type of token (jwt/api)
103
+ token_data: Token data dictionary containing:
104
+ - roles: List of roles for the token
105
+ - expires_in: Token expiration time in seconds (optional)
106
+ - description: Token description (optional)
107
+ - user_id: User ID associated with token (optional)
108
+
109
+ Returns:
110
+ CommandResult with created token information
111
+ """
112
+ try:
113
+ if token_type not in ["jwt", "api"]:
114
+ return ErrorResult(
115
+ message=f"Unsupported token type: {token_type}", code=-32602
116
+ )
117
+
118
+ if token_type == "jwt":
119
+ return await self._create_jwt_token(token_data)
120
+ else:
121
+ return await self._create_api_token(token_data)
122
+
123
+ except Exception as e:
124
+ self.get_global_logger().error(f"Token creation error: {e}")
125
+ return ErrorResult(message=f"Token creation failed: {str(e)}", code=-32603)
126
+
127
+ async def token_validate(
128
+ self, token: str, token_type: str = "auto"
129
+ ) -> Union[SuccessResult, ErrorResult]:
130
+ """
131
+ Validate a token.
132
+
133
+ Args:
134
+ token: Token string to validate
135
+ token_type: Type of token (auto/jwt/api)
136
+
137
+ Returns:
138
+ CommandResult with validation status and token information
139
+ """
140
+ try:
141
+ if not token:
142
+ return ErrorResult(message="Token not provided", code=-32602)
143
+
144
+ # Auto-detect token type if not specified
145
+ if token_type == "auto":
146
+ token_type = "jwt" if self._is_jwt_token(token) else "api"
147
+
148
+ # Use AuthValidator for validation
149
+ result = self.auth_validator.validate_token(token, token_type)
150
+
151
+ if result.is_valid:
152
+ return SuccessResult(
153
+ data={
154
+ "valid": True,
155
+ "token_type": token_type,
156
+ "roles": result.roles,
157
+ "expires_at": self._get_token_expiry(token, token_type),
158
+ }
159
+ )
160
+ else:
161
+ error_data = result.to_json_rpc_error()
162
+ return ErrorResult(
163
+ message=error_data["message"], code=error_data["code"]
164
+ )
165
+
166
+ except Exception as e:
167
+ self.get_global_logger().error(f"Token validation error: {e}")
168
+ return ErrorResult(
169
+ message=f"Token validation failed: {str(e)}", code=-32603
170
+ )
171
+
172
+ async def token_revoke(self, token: str) -> Union[SuccessResult, ErrorResult]:
173
+ """
174
+ Revoke a token.
175
+
176
+ Args:
177
+ token: Token string to revoke
178
+
179
+ Returns:
180
+ CommandResult with revocation status
181
+ """
182
+ try:
183
+ if not token:
184
+ return ErrorResult(message="Token not provided", code=-32602)
185
+
186
+ # Load current tokens
187
+ tokens = self._load_tokens()
188
+
189
+ # Check if token exists
190
+ if token not in tokens:
191
+ return ErrorResult(message="Token not found", code=-32011)
192
+
193
+ # Mark token as revoked
194
+ tokens[token]["active"] = False
195
+ tokens[token]["revoked_at"] = time.time()
196
+ tokens[token]["revoked_by"] = "system"
197
+
198
+ # Save updated tokens
199
+ self._save_tokens(tokens)
200
+
201
+ return SuccessResult(
202
+ data={
203
+ "revoked": True,
204
+ "token": token,
205
+ "revoked_at": datetime.now().isoformat(),
206
+ }
207
+ )
208
+
209
+ except Exception as e:
210
+ self.get_global_logger().error(f"Token revocation error: {e}")
211
+ return ErrorResult(
212
+ message=f"Token revocation failed: {str(e)}", code=-32603
213
+ )
214
+
215
+ async def token_list(
216
+ self, active_only: bool = True
217
+ ) -> Union[SuccessResult, ErrorResult]:
218
+ """
219
+ List all tokens.
220
+
221
+ Args:
222
+ active_only: If True, return only active tokens
223
+
224
+ Returns:
225
+ CommandResult with list of tokens
226
+ """
227
+ try:
228
+ # Load tokens
229
+ tokens = self._load_tokens()
230
+
231
+ # Filter tokens if requested
232
+ if active_only:
233
+ tokens = {k: v for k, v in tokens.items() if v.get("active", True)}
234
+
235
+ # Prepare token list (without sensitive data)
236
+ token_list = []
237
+ for token_id, token_data in tokens.items():
238
+ token_info = {
239
+ "id": token_id,
240
+ "type": token_data.get("type", "api"),
241
+ "roles": token_data.get("roles", []),
242
+ "active": token_data.get("active", True),
243
+ "created_at": token_data.get("created_at"),
244
+ "expires_at": token_data.get("expires_at"),
245
+ "description": token_data.get("description", ""),
246
+ "user_id": token_data.get("user_id"),
247
+ }
248
+
249
+ if "revoked_at" in token_data:
250
+ token_info["revoked_at"] = token_data["revoked_at"]
251
+
252
+ token_list.append(token_info)
253
+
254
+ return SuccessResult(
255
+ data={
256
+ "tokens": token_list,
257
+ "count": len(token_list),
258
+ "active_only": active_only,
259
+ }
260
+ )
261
+
262
+ except Exception as e:
263
+ self.get_global_logger().error(f"Token listing error: {e}")
264
+ return ErrorResult(message=f"Token listing failed: {str(e)}", code=-32603)
265
+
266
+ async def token_refresh(self, token: str) -> Union[SuccessResult, ErrorResult]:
267
+ """
268
+ Refresh a token.
269
+
270
+ Args:
271
+ token: Token string to refresh
272
+
273
+ Returns:
274
+ CommandResult with refreshed token information
275
+ """
276
+ try:
277
+ if not token:
278
+ return ErrorResult(message="Token not provided", code=-32602)
279
+
280
+ # Load current tokens
281
+ tokens = self._load_tokens()
282
+
283
+ # Check if token exists and is active
284
+ if token not in tokens:
285
+ return ErrorResult(message="Token not found", code=-32011)
286
+
287
+ token_data = tokens[token]
288
+ if not token_data.get("active", True):
289
+ return ErrorResult(message="Token is revoked", code=-32011)
290
+
291
+ # Check if token has expired
292
+ if "expires_at" in token_data and time.time() > token_data["expires_at"]:
293
+ return ErrorResult(message="Token has expired", code=-32010)
294
+
295
+ # Create new token with same data
296
+ new_token_data = {
297
+ "type": token_data.get("type", "api"),
298
+ "roles": token_data.get("roles", []),
299
+ "active": True,
300
+ "created_at": time.time(),
301
+ "expires_at": time.time() + self.token_expiry,
302
+ "description": token_data.get("description", ""),
303
+ "user_id": token_data.get("user_id"),
304
+ "refreshed_from": token,
305
+ }
306
+
307
+ # Generate new token ID
308
+ new_token_id = str(uuid.uuid4())
309
+ tokens[new_token_id] = new_token_data
310
+
311
+ # Revoke old token
312
+ tokens[token]["active"] = False
313
+ tokens[token]["refreshed_to"] = new_token_id
314
+ tokens[token]["refreshed_at"] = time.time()
315
+
316
+ # Save updated tokens
317
+ self._save_tokens(tokens)
318
+
319
+ return SuccessResult(
320
+ data={
321
+ "refreshed": True,
322
+ "old_token": token,
323
+ "new_token": new_token_id,
324
+ "expires_at": new_token_data["expires_at"],
325
+ }
326
+ )
327
+
328
+ except Exception as e:
329
+ self.get_global_logger().error(f"Token refresh error: {e}")
330
+ return ErrorResult(message=f"Token refresh failed: {str(e)}", code=-32603)
331
+
332
+ async def _create_jwt_token(
333
+ self, token_data: Dict[str, Any]
334
+ ) -> Union[SuccessResult, ErrorResult]:
335
+ """
336
+ Create JWT token.
337
+
338
+ Args:
339
+ token_data: Token data dictionary
340
+
341
+ Returns:
342
+ CommandResult with JWT token
343
+ """
344
+ try:
345
+ # This is a placeholder for JWT creation
346
+ # In a real implementation, you would use a JWT library like PyJWT
347
+
348
+ # For now, create a simple token structure
349
+ token_id = str(uuid.uuid4())
350
+ expires_in = token_data.get("expires_in", self.token_expiry)
351
+
352
+ jwt_token_data = {
353
+ "jti": token_id,
354
+ "sub": token_data.get("user_id", "system"),
355
+ "roles": token_data.get("roles", []),
356
+ "exp": time.time() + expires_in,
357
+ "iat": time.time(),
358
+ "iss": "mcp_proxy_adapter",
359
+ }
360
+
361
+ # In a real implementation, you would encode this as JWT
362
+ # For now, return the token data
363
+ return SuccessResult(
364
+ data={
365
+ "token": token_id,
366
+ "token_type": "jwt",
367
+ "expires_at": jwt_token_data["exp"],
368
+ "roles": jwt_token_data["roles"],
369
+ "user_id": jwt_token_data["sub"],
370
+ }
371
+ )
372
+
373
+ except Exception as e:
374
+ self.get_global_logger().error(f"JWT token creation error: {e}")
375
+ return ErrorResult(
376
+ message=f"JWT token creation failed: {str(e)}", code=-32603
377
+ )
378
+
379
+ async def _create_api_token(
380
+ self, token_data: Dict[str, Any]
381
+ ) -> Union[SuccessResult, ErrorResult]:
382
+ """
383
+ Create API token.
384
+
385
+ Args:
386
+ token_data: Token data dictionary
387
+
388
+ Returns:
389
+ CommandResult with API token
390
+ """
391
+ try:
392
+ # Generate token ID
393
+ token_id = str(uuid.uuid4())
394
+ expires_in = token_data.get("expires_in", self.token_expiry)
395
+
396
+ # Create token data
397
+ api_token_data = {
398
+ "type": "api",
399
+ "roles": token_data.get("roles", []),
400
+ "active": True,
401
+ "created_at": time.time(),
402
+ "expires_at": time.time() + expires_in,
403
+ "description": token_data.get("description", ""),
404
+ "user_id": token_data.get("user_id"),
405
+ }
406
+
407
+ # Load current tokens and add new token
408
+ tokens = self._load_tokens()
409
+ tokens[token_id] = api_token_data
410
+ self._save_tokens(tokens)
411
+
412
+ return SuccessResult(
413
+ data={
414
+ "token": token_id,
415
+ "token_type": "api",
416
+ "expires_at": api_token_data["expires_at"],
417
+ "roles": api_token_data["roles"],
418
+ "user_id": api_token_data["user_id"],
419
+ }
420
+ )
421
+
422
+ except Exception as e:
423
+ self.get_global_logger().error(f"API token creation error: {e}")
424
+ return ErrorResult(
425
+ message=f"API token creation failed: {str(e)}", code=-32603
426
+ )
427
+
428
+ def _is_jwt_token(self, token: str) -> bool:
429
+ """
430
+ Check if token is JWT format.
431
+
432
+ Args:
433
+ token: Token string
434
+
435
+ Returns:
436
+ True if token appears to be JWT, False otherwise
437
+ """
438
+ parts = token.split(".")
439
+ return len(parts) == 3
440
+
441
+ def _get_token_expiry(self, token: str, token_type: str) -> Optional[float]:
442
+ """
443
+ Get token expiry time.
444
+
445
+ Args:
446
+ token: Token string
447
+ token_type: Type of token
448
+
449
+ Returns:
450
+ Expiry timestamp or None
451
+ """
452
+ try:
453
+ if token_type == "api":
454
+ tokens = self._load_tokens()
455
+ if token in tokens:
456
+ return tokens[token].get("expires_at")
457
+
458
+ # For JWT tokens, this would require decoding
459
+ # For now, return None
460
+ return None
461
+
462
+ except Exception as e:
463
+ self.get_global_logger().error(f"Failed to get token expiry: {e}")
464
+ return None
465
+
466
+ def _load_tokens(self) -> Dict[str, Any]:
467
+ """
468
+ Load tokens from file.
469
+
470
+ Returns:
471
+ Dictionary of tokens
472
+ """
473
+ try:
474
+ if not self.tokens_file or not Path(self.tokens_file).exists():
475
+ return {}
476
+
477
+ with open(self.tokens_file, "r", encoding="utf-8") as f:
478
+ return json.load(f)
479
+
480
+ except Exception as e:
481
+ self.get_global_logger().error(f"Failed to load tokens: {e}")
482
+ return {}
483
+
484
+ def _save_tokens(self, tokens: Dict[str, Any]) -> None:
485
+ """
486
+ Save tokens to file.
487
+
488
+ Args:
489
+ tokens: Dictionary of tokens to save
490
+ """
491
+ try:
492
+ # Ensure directory exists
493
+ Path(self.tokens_file).parent.mkdir(parents=True, exist_ok=True)
494
+
495
+ with open(self.tokens_file, "w", encoding="utf-8") as f:
496
+ json.dump(tokens, f, indent=2, ensure_ascii=False)
497
+
498
+ except Exception as e:
499
+ self.get_global_logger().error(f"Failed to save tokens: {e}")
500
+ raise
@@ -0,0 +1,129 @@
1
+ """
2
+ Transport Management Command
3
+
4
+ This command provides transport management functionality for the MCP Proxy Adapter.
5
+ """
6
+
7
+ from mcp_proxy_adapter.commands.base import Command
8
+ from mcp_proxy_adapter.core.transport_manager import transport_manager
9
+ from mcp_proxy_adapter.core.logging import get_global_logger
10
+
11
+
12
+ class TransportManagementResult(SuccessResult):
13
+ """Result class for transport management operations."""
14
+
15
+ def __init__(
16
+ self,
17
+ transport_info: Dict[str, Any],
18
+ message: str = "Transport management operation completed",
19
+ ):
20
+ """
21
+ Initialize transport management result.
22
+
23
+ Args:
24
+ transport_info: Transport information
25
+ message: Success message
26
+ """
27
+ super().__init__(data={"transport_info": transport_info}, message=message)
28
+
29
+
30
+ class TransportManagementCommand(Command):
31
+ """
32
+ Transport management command.
33
+
34
+ This command provides functionality to manage and query transport configurations.
35
+ """
36
+
37
+ name = "transport_management"
38
+ descr = "Manage and query transport configurations (HTTP, HTTPS, MTLS)"
39
+
40
+ @classmethod
41
+
42
+ async def execute(self, **params) -> TransportManagementResult:
43
+ """
44
+ Execute transport management command.
45
+
46
+ Args:
47
+ params: Command parameters
48
+
49
+ Returns:
50
+ Transport management result
51
+ """
52
+ try:
53
+ action = params.get("action", "get_info")
54
+
55
+ if action == "get_info":
56
+ return await self._get_transport_info()
57
+ elif action == "validate":
58
+ return await self._validate_transport()
59
+ elif action == "reload":
60
+ return await self._reload_transport()
61
+ else:
62
+ return TransportManagementResult(
63
+ transport_info={"error": f"Unknown action: {action}"},
64
+ message=f"Unknown action: {action}",
65
+ )
66
+
67
+ except Exception as e:
68
+ get_global_logger().error(f"Transport management command error: {e}")
69
+ return TransportManagementResult(
70
+ transport_info={"error": str(e)},
71
+ message=f"Transport management failed: {e}",
72
+ )
73
+
74
+ async def _get_transport_info(self) -> TransportManagementResult:
75
+ """
76
+ Get transport information.
77
+
78
+ Returns:
79
+ Transport information result
80
+ """
81
+ transport_info = transport_manager.get_transport_info()
82
+
83
+ return TransportManagementResult(
84
+ transport_info=transport_info,
85
+ message="Transport information retrieved successfully",
86
+ )
87
+
88
+ async def _validate_transport(self) -> TransportManagementResult:
89
+ """
90
+ Validate transport configuration.
91
+
92
+ Returns:
93
+ Validation result
94
+ """
95
+ is_valid = transport_manager.validate_config()
96
+
97
+ transport_info = transport_manager.get_transport_info()
98
+ transport_info["validation"] = {
99
+ "is_valid": is_valid,
100
+ "timestamp": "2025-08-15T12:00:00Z",
101
+ }
102
+
103
+ message = (
104
+ "Transport configuration validated successfully"
105
+ if is_valid
106
+ else "Transport configuration validation failed"
107
+ )
108
+
109
+ return TransportManagementResult(transport_info=transport_info, message=message)
110
+
111
+ async def _reload_transport(self) -> TransportManagementResult:
112
+ """
113
+ Reload transport configuration.
114
+
115
+ Returns:
116
+ Reload result
117
+ """
118
+ # Note: In a real implementation, this would reload the config
119
+ # For now, we just return current info
120
+ transport_info = transport_manager.get_transport_info()
121
+ transport_info["reload"] = {
122
+ "status": "completed",
123
+ "timestamp": "2025-08-15T12:00:00Z",
124
+ }
125
+
126
+ return TransportManagementResult(
127
+ transport_info=transport_info,
128
+ message="Transport configuration reload completed",
129
+ )