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,267 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Complete framework testing with real MCP servers.
4
+
5
+ Author: Vasiliy Zdanovskiy
6
+ email: vasilyvz@gmail.com
7
+ """
8
+
9
+ import asyncio
10
+ import json
11
+ import subprocess
12
+ import time
13
+ import requests
14
+ import ssl
15
+ from pathlib import Path
16
+
17
+ # Configure logging
18
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
19
+ logger = logging.getLogger(__name__)
20
+
21
+ class FrameworkTester:
22
+ """Complete framework testing with real MCP servers."""
23
+
24
+ def __init__(self):
25
+ self.project_root = Path(__file__).parent.parent.parent
26
+ self.configs_dir = self.project_root / "configs"
27
+ self.examples_dir = Path(__file__).parent
28
+ self.test_results = []
29
+ self.server_processes = []
30
+
31
+ async def test_all_protocols(self):
32
+ """Test all protocols with real MCP server registration."""
33
+ get_global_logger().info("🧪 Starting Complete Framework Testing")
34
+ get_global_logger().info("=" * 60)
35
+
36
+ # Test configurations
37
+ test_configs = [
38
+ ("http.json", "HTTP", 20000),
39
+ ("https.json", "HTTPS", 20003),
40
+ ("mtls.json", "mTLS", 20006)
41
+ ]
42
+
43
+ for config_file, protocol, port in test_configs:
44
+ get_global_logger().info(f"\n🔧 Testing {protocol} (port {port})")
45
+ get_global_logger().info("-" * 40)
46
+
47
+ try:
48
+ # Start proxy adapter server
49
+ proxy_process = await self._start_proxy_server(config_file, port)
50
+ if not proxy_process:
51
+ continue
52
+
53
+ # Wait for server to start
54
+ await asyncio.sleep(2)
55
+
56
+ # Test server registration
57
+ await self._test_server_registration(protocol, port)
58
+
59
+ # Test MCP communication
60
+ await self._test_mcp_communication(protocol, port)
61
+
62
+ # Test security features
63
+ await self._test_security_features(protocol, port)
64
+
65
+ # Stop server
66
+ proxy_process.terminate()
67
+ await asyncio.sleep(1)
68
+
69
+ get_global_logger().info(f"✅ {protocol} testing completed successfully")
70
+
71
+ except Exception as e:
72
+ get_global_logger().error(f"❌ {protocol} testing failed: {e}")
73
+ self.test_results.append({
74
+ "protocol": protocol,
75
+ "status": "failed",
76
+ "error": str(e)
77
+ })
78
+
79
+ # Print summary
80
+ self._print_summary()
81
+
82
+ async def _start_proxy_server(self, config_file: str, port: int) -> Optional[subprocess.Popen]:
83
+ """Start proxy adapter server."""
84
+ config_path = self.configs_dir / config_file
85
+
86
+ if not config_path.exists():
87
+ get_global_logger().error(f"❌ Config file not found: {config_path}")
88
+ return None
89
+
90
+ get_global_logger().info(f"🚀 Starting proxy server with {config_file}")
91
+
92
+ try:
93
+ # Start server in background
94
+ process = subprocess.Popen([
95
+ "python", str(self.examples_dir / "main.py"),
96
+ "--config", str(config_path)
97
+ ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
98
+
99
+ self.server_processes.append(process)
100
+ return process
101
+
102
+ except Exception as e:
103
+ get_global_logger().error(f"❌ Failed to start server: {e}")
104
+ return None
105
+
106
+ async def _test_server_registration(self, protocol: str, port: int):
107
+ """Test MCP server registration."""
108
+ get_global_logger().info(f"📝 Testing server registration for {protocol}")
109
+
110
+ base_url = f"http://localhost:{port}" if protocol == "HTTP" else f"https://localhost:{port}"
111
+
112
+ # Test registration endpoint
113
+ registration_data = {
114
+ "server_id": "test-mcp-server",
115
+ "server_url": "stdio://test-server",
116
+ "server_name": "Test MCP Server",
117
+ "description": "Test server for framework validation"
118
+ }
119
+
120
+ try:
121
+ # Create SSL context for HTTPS/mTLS
122
+ ssl_context = None
123
+ if protocol in ["HTTPS", "mTLS"]:
124
+ ssl_context = ssl.create_default_context()
125
+ ssl_context.check_hostname = False
126
+ ssl_context.verify_mode = ssl.CERT_NONE
127
+
128
+ response = requests.post(
129
+ f"{base_url}/register",
130
+ json=registration_data,
131
+ verify=False,
132
+ timeout=10
133
+ )
134
+
135
+ if response.status_code == 200:
136
+ get_global_logger().info("✅ Server registration successful")
137
+ else:
138
+ get_global_logger().warning(f"⚠️ Registration returned status {response.status_code}")
139
+
140
+ except Exception as e:
141
+ get_global_logger().error(f"❌ Registration failed: {e}")
142
+ raise
143
+
144
+ async def _test_mcp_communication(self, protocol: str, port: int):
145
+ """Test MCP communication through proxy."""
146
+ get_global_logger().info(f"🔗 Testing MCP communication for {protocol}")
147
+
148
+ base_url = f"http://localhost:{port}" if protocol == "HTTP" else f"https://localhost:{port}"
149
+
150
+ # Test MCP JSON-RPC call
151
+ mcp_request = {
152
+ "jsonrpc": "2.0",
153
+ "id": 1,
154
+ "method": "tools/list",
155
+ "params": {}
156
+ }
157
+
158
+ try:
159
+ ssl_context = None
160
+ if protocol in ["HTTPS", "mTLS"]:
161
+ ssl_context = ssl.create_default_context()
162
+ ssl_context.check_hostname = False
163
+ ssl_context.verify_mode = ssl.CERT_NONE
164
+
165
+ response = requests.post(
166
+ f"{base_url}/mcp",
167
+ json=mcp_request,
168
+ headers={"Content-Type": "application/json"},
169
+ verify=False,
170
+ timeout=10
171
+ )
172
+
173
+ if response.status_code == 200:
174
+ result = response.json()
175
+ if "result" in result:
176
+ get_global_logger().info("✅ MCP communication successful")
177
+ else:
178
+ get_global_logger().warning(f"⚠️ MCP response: {result}")
179
+ else:
180
+ get_global_logger().warning(f"⚠️ MCP call returned status {response.status_code}")
181
+
182
+ except Exception as e:
183
+ get_global_logger().error(f"❌ MCP communication failed: {e}")
184
+ raise
185
+
186
+ async def _test_security_features(self, protocol: str, port: int):
187
+ """Test security features."""
188
+ get_global_logger().info(f"🔒 Testing security features for {protocol}")
189
+
190
+ base_url = f"http://localhost:{port}" if protocol == "HTTP" else f"https://localhost:{port}"
191
+
192
+ # Test without authentication
193
+ try:
194
+ ssl_context = None
195
+ if protocol in ["HTTPS", "mTLS"]:
196
+ ssl_context = ssl.create_default_context()
197
+ ssl_context.check_hostname = False
198
+ ssl_context.verify_mode = ssl.CERT_NONE
199
+
200
+ response = requests.get(
201
+ f"{base_url}/health",
202
+ verify=False,
203
+ timeout=10
204
+ )
205
+
206
+ if response.status_code == 200:
207
+ get_global_logger().info("✅ Health check successful")
208
+ else:
209
+ get_global_logger().warning(f"⚠️ Health check returned status {response.status_code}")
210
+
211
+ except Exception as e:
212
+ get_global_logger().error(f"❌ Security test failed: {e}")
213
+ raise
214
+
215
+ def _print_summary(self):
216
+ """Print test summary."""
217
+ get_global_logger().info("\n" + "=" * 60)
218
+ get_global_logger().info("📊 FRAMEWORK TESTING SUMMARY")
219
+ get_global_logger().info("=" * 60)
220
+
221
+ total_tests = len(self.test_results)
222
+ successful_tests = len([r for r in self.test_results if r["status"] == "success"])
223
+
224
+ get_global_logger().info(f"Total tests: {total_tests}")
225
+ get_global_logger().info(f"Successful: {successful_tests}")
226
+ get_global_logger().info(f"Failed: {total_tests - successful_tests}")
227
+
228
+ if total_tests > 0:
229
+ success_rate = (successful_tests / total_tests) * 100
230
+ get_global_logger().info(f"Success rate: {success_rate:.1f}%")
231
+
232
+ if success_rate == 100:
233
+ get_global_logger().info("🎉 All tests passed! Framework is working correctly.")
234
+ elif success_rate >= 80:
235
+ get_global_logger().info("✅ Most tests passed. Framework is mostly functional.")
236
+ else:
237
+ get_global_logger().info("⚠️ Many tests failed. Framework needs attention.")
238
+
239
+ get_global_logger().info("=" * 60)
240
+
241
+ async def cleanup(self):
242
+ """Cleanup server processes."""
243
+ get_global_logger().info("🧹 Cleaning up server processes...")
244
+
245
+ for process in self.server_processes:
246
+ try:
247
+ if process.poll() is None: # Process is still running
248
+ process.terminate()
249
+ process.wait(timeout=5)
250
+ except subprocess.TimeoutExpired:
251
+ process.kill()
252
+ except Exception as e:
253
+ get_global_logger().warning(f"Warning: Failed to cleanup process: {e}")
254
+
255
+ self.server_processes.clear()
256
+
257
+ async def main():
258
+ """Main testing function."""
259
+ tester = FrameworkTester()
260
+
261
+ try:
262
+ await tester.test_all_protocols()
263
+ finally:
264
+ await tester.cleanup()
265
+
266
+ if __name__ == "__main__":
267
+ asyncio.run(main())
@@ -0,0 +1,187 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test MCP Server for framework validation.
4
+
5
+ Author: Vasiliy Zdanovskiy
6
+ email: vasilyvz@gmail.com
7
+ """
8
+
9
+ import asyncio
10
+ import json
11
+ import logging
12
+ from mcp import types
13
+ from mcp.server import Server
14
+ from mcp.server.stdio import stdio_server
15
+
16
+ # Configure logging
17
+ logging.basicConfig(level=logging.INFO)
18
+ logger = logging.getLogger(__name__)
19
+
20
+ class TestMCPServer:
21
+ """Test MCP Server for framework validation."""
22
+
23
+ def __init__(self):
24
+ self.server = Server("test-mcp-server")
25
+ self._setup_handlers()
26
+
27
+ def _setup_handlers(self):
28
+ """Setup MCP server handlers."""
29
+
30
+ @self.server.list_tools()
31
+ async def list_tools() -> List[types.Tool]:
32
+ """List available tools."""
33
+ return [
34
+ types.Tool(
35
+ name="echo",
36
+ description="Echo back the input message",
37
+ inputSchema={
38
+ "type": "object",
39
+ "properties": {
40
+ "message": {
41
+ "type": "string",
42
+ "description": "Message to echo back"
43
+ }
44
+ },
45
+ "required": ["message"]
46
+ }
47
+ ),
48
+ types.Tool(
49
+ name="add",
50
+ description="Add two numbers",
51
+ inputSchema={
52
+ "type": "object",
53
+ "properties": {
54
+ "a": {
55
+ "type": "number",
56
+ "description": "First number"
57
+ },
58
+ "b": {
59
+ "type": "number",
60
+ "description": "Second number"
61
+ }
62
+ },
63
+ "required": ["a", "b"]
64
+ }
65
+ ),
66
+ types.Tool(
67
+ name="get_info",
68
+ description="Get server information",
69
+ inputSchema={
70
+ "type": "object",
71
+ "properties": {}
72
+ }
73
+ )
74
+ ]
75
+
76
+ @self.server.call_tool()
77
+ async def call_tool(name: str, arguments: Dict[str, Any]) -> List[types.TextContent]:
78
+ """Handle tool calls."""
79
+ get_global_logger().info(f"Tool called: {name} with args: {arguments}")
80
+
81
+ if name == "echo":
82
+ message = arguments.get("message", "")
83
+ return [types.TextContent(type="text", text=f"Echo: {message}")]
84
+
85
+ elif name == "add":
86
+ a = arguments.get("a", 0)
87
+ b = arguments.get("b", 0)
88
+ result = a + b
89
+ return [types.TextContent(type="text", text=f"Result: {a} + {b} = {result}")]
90
+
91
+ elif name == "get_info":
92
+ info = {
93
+ "server_name": "test-mcp-server",
94
+ "version": "1.0.0",
95
+ "status": "running",
96
+ "tools_count": 3
97
+ }
98
+ return [types.TextContent(type="text", text=json.dumps(info, indent=2))]
99
+
100
+ else:
101
+ return [types.TextContent(type="text", text=f"Unknown tool: {name}")]
102
+
103
+ @self.server.list_resources()
104
+ async def list_resources() -> List[types.Resource]:
105
+ """List available resources."""
106
+ return [
107
+ types.Resource(
108
+ uri="test://config",
109
+ name="Server Configuration",
110
+ description="Current server configuration",
111
+ mimeType="application/json"
112
+ ),
113
+ types.Resource(
114
+ uri="test://status",
115
+ name="Server Status",
116
+ description="Current server status",
117
+ mimeType="application/json"
118
+ )
119
+ ]
120
+
121
+ @self.server.read_resource()
122
+ async def read_resource(uri: str) -> str:
123
+ """Read resource content."""
124
+ if uri == "test://config":
125
+ config = {
126
+ "server_name": "test-mcp-server",
127
+ "port": 3001,
128
+ "protocol": "stdio",
129
+ "features": ["tools", "resources"]
130
+ }
131
+ return json.dumps(config, indent=2)
132
+
133
+ elif uri == "test://status":
134
+ status = {
135
+ "status": "running",
136
+ "uptime": "0s",
137
+ "requests_handled": 0,
138
+ "last_request": None
139
+ }
140
+ return json.dumps(status, indent=2)
141
+
142
+ else:
143
+ raise ValueError(f"Unknown resource: {uri}")
144
+
145
+ @self.server.list_prompts()
146
+ async def list_prompts() -> List[types.Prompt]:
147
+ """List available prompts."""
148
+ return [
149
+ types.Prompt(
150
+ name="greeting",
151
+ description="Generate a greeting message",
152
+ arguments=[
153
+ types.PromptArgument(
154
+ name="name",
155
+ description="Name to greet",
156
+ required=True
157
+ )
158
+ ]
159
+ )
160
+ ]
161
+
162
+ @self.server.get_prompt()
163
+ async def get_prompt(name: str, arguments: Dict[str, str]) -> List[types.TextContent]:
164
+ """Get prompt content."""
165
+ if name == "greeting":
166
+ user_name = arguments.get("name", "User")
167
+ greeting = f"Hello, {user_name}! Welcome to the test MCP server."
168
+ return [types.TextContent(type="text", text=greeting)]
169
+
170
+ else:
171
+ raise ValueError(f"Unknown prompt: {name}")
172
+
173
+ async def main():
174
+ """Main server function."""
175
+ get_global_logger().info("Starting Test MCP Server...")
176
+
177
+ server_instance = TestMCPServer()
178
+
179
+ async with stdio_server() as (read_stream, write_stream):
180
+ await server_instance.server.run(
181
+ read_stream,
182
+ write_stream,
183
+ server_instance.server.create_initialization_options()
184
+ )
185
+
186
+ if __name__ == "__main__":
187
+ asyncio.run(main())