mcp-proxy-adapter 6.9.28__py3-none-any.whl → 6.9.29__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 (212) hide show
  1. mcp_proxy_adapter/__init__.py +10 -0
  2. mcp_proxy_adapter/__main__.py +8 -21
  3. mcp_proxy_adapter/api/app.py +10 -913
  4. mcp_proxy_adapter/api/core/__init__.py +18 -0
  5. mcp_proxy_adapter/api/core/app_factory.py +243 -0
  6. mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
  7. mcp_proxy_adapter/api/core/registration_manager.py +166 -0
  8. mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
  9. mcp_proxy_adapter/api/handlers.py +78 -199
  10. mcp_proxy_adapter/api/middleware/__init__.py +1 -44
  11. mcp_proxy_adapter/api/middleware/base.py +0 -42
  12. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -85
  13. mcp_proxy_adapter/api/middleware/error_handling.py +1 -127
  14. mcp_proxy_adapter/api/middleware/factory.py +0 -94
  15. mcp_proxy_adapter/api/middleware/logging.py +0 -112
  16. mcp_proxy_adapter/api/middleware/performance.py +0 -35
  17. mcp_proxy_adapter/api/middleware/protocol_middleware.py +2 -98
  18. mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -37
  19. mcp_proxy_adapter/api/middleware/unified_security.py +10 -10
  20. mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -118
  21. mcp_proxy_adapter/api/openapi/__init__.py +21 -0
  22. mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
  23. mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
  24. mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
  25. mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
  26. mcp_proxy_adapter/api/schemas.py +0 -61
  27. mcp_proxy_adapter/api/tool_integration.py +0 -117
  28. mcp_proxy_adapter/api/tools.py +0 -46
  29. mcp_proxy_adapter/cli/__init__.py +12 -0
  30. mcp_proxy_adapter/cli/commands/__init__.py +15 -0
  31. mcp_proxy_adapter/cli/commands/client.py +100 -0
  32. mcp_proxy_adapter/cli/commands/config_generate.py +21 -0
  33. mcp_proxy_adapter/cli/commands/config_validate.py +36 -0
  34. mcp_proxy_adapter/cli/commands/generate.py +259 -0
  35. mcp_proxy_adapter/cli/commands/server.py +174 -0
  36. mcp_proxy_adapter/cli/commands/sets.py +128 -0
  37. mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
  38. mcp_proxy_adapter/cli/examples/__init__.py +8 -0
  39. mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
  40. mcp_proxy_adapter/cli/examples/https_token.py +96 -0
  41. mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
  42. mcp_proxy_adapter/cli/main.py +63 -0
  43. mcp_proxy_adapter/cli/parser.py +324 -0
  44. mcp_proxy_adapter/cli/validators.py +231 -0
  45. mcp_proxy_adapter/client/jsonrpc_client.py +406 -0
  46. mcp_proxy_adapter/client/proxy.py +45 -0
  47. mcp_proxy_adapter/commands/__init__.py +44 -28
  48. mcp_proxy_adapter/commands/auth_validation_command.py +7 -344
  49. mcp_proxy_adapter/commands/base.py +19 -43
  50. mcp_proxy_adapter/commands/builtin_commands.py +0 -75
  51. mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
  52. mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
  53. mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
  54. mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
  55. mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
  56. mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
  57. mcp_proxy_adapter/commands/catalog_manager.py +58 -928
  58. mcp_proxy_adapter/commands/cert_monitor_command.py +0 -88
  59. mcp_proxy_adapter/commands/certificate_management_command.py +0 -45
  60. mcp_proxy_adapter/commands/command_registry.py +172 -904
  61. mcp_proxy_adapter/commands/config_command.py +0 -28
  62. mcp_proxy_adapter/commands/dependency_container.py +1 -70
  63. mcp_proxy_adapter/commands/dependency_manager.py +0 -128
  64. mcp_proxy_adapter/commands/echo_command.py +0 -34
  65. mcp_proxy_adapter/commands/health_command.py +0 -3
  66. mcp_proxy_adapter/commands/help_command.py +0 -159
  67. mcp_proxy_adapter/commands/hooks.py +0 -137
  68. mcp_proxy_adapter/commands/key_management_command.py +0 -25
  69. mcp_proxy_adapter/commands/load_command.py +7 -78
  70. mcp_proxy_adapter/commands/plugins_command.py +0 -16
  71. mcp_proxy_adapter/commands/protocol_management_command.py +0 -28
  72. mcp_proxy_adapter/commands/proxy_registration_command.py +0 -88
  73. mcp_proxy_adapter/commands/queue_commands.py +750 -0
  74. mcp_proxy_adapter/commands/registration_status_command.py +0 -43
  75. mcp_proxy_adapter/commands/registry/__init__.py +18 -0
  76. mcp_proxy_adapter/commands/registry/command_info.py +103 -0
  77. mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
  78. mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
  79. mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
  80. mcp_proxy_adapter/commands/reload_command.py +0 -80
  81. mcp_proxy_adapter/commands/result.py +25 -77
  82. mcp_proxy_adapter/commands/role_test_command.py +0 -44
  83. mcp_proxy_adapter/commands/roles_management_command.py +0 -199
  84. mcp_proxy_adapter/commands/security_command.py +0 -30
  85. mcp_proxy_adapter/commands/settings_command.py +0 -68
  86. mcp_proxy_adapter/commands/ssl_setup_command.py +0 -42
  87. mcp_proxy_adapter/commands/token_management_command.py +0 -1
  88. mcp_proxy_adapter/commands/transport_management_command.py +0 -20
  89. mcp_proxy_adapter/commands/unload_command.py +0 -71
  90. mcp_proxy_adapter/config.py +15 -626
  91. mcp_proxy_adapter/core/__init__.py +5 -39
  92. mcp_proxy_adapter/core/app_factory.py +14 -36
  93. mcp_proxy_adapter/core/app_runner.py +0 -27
  94. mcp_proxy_adapter/core/auth_validator.py +1 -93
  95. mcp_proxy_adapter/core/certificate/__init__.py +20 -0
  96. mcp_proxy_adapter/core/certificate/certificate_creator.py +371 -0
  97. mcp_proxy_adapter/core/certificate/certificate_extractor.py +183 -0
  98. mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
  99. mcp_proxy_adapter/core/certificate/certificate_validator.py +110 -0
  100. mcp_proxy_adapter/core/certificate/ssl_context_manager.py +70 -0
  101. mcp_proxy_adapter/core/certificate_utils.py +64 -903
  102. mcp_proxy_adapter/core/client.py +0 -6
  103. mcp_proxy_adapter/core/client_manager.py +0 -19
  104. mcp_proxy_adapter/core/client_security.py +0 -2
  105. mcp_proxy_adapter/core/config/__init__.py +18 -0
  106. mcp_proxy_adapter/core/config/config.py +195 -0
  107. mcp_proxy_adapter/core/config/config_factory.py +22 -0
  108. mcp_proxy_adapter/core/config/config_loader.py +66 -0
  109. mcp_proxy_adapter/core/config/feature_manager.py +31 -0
  110. mcp_proxy_adapter/core/config/simple_config.py +112 -0
  111. mcp_proxy_adapter/core/config/simple_config_generator.py +50 -0
  112. mcp_proxy_adapter/core/config/simple_config_validator.py +96 -0
  113. mcp_proxy_adapter/core/config_converter.py +0 -186
  114. mcp_proxy_adapter/core/config_validator.py +96 -1238
  115. mcp_proxy_adapter/core/errors.py +7 -42
  116. mcp_proxy_adapter/core/job_manager.py +54 -0
  117. mcp_proxy_adapter/core/logging.py +2 -22
  118. mcp_proxy_adapter/core/mtls_asgi.py +0 -20
  119. mcp_proxy_adapter/core/mtls_asgi_app.py +0 -12
  120. mcp_proxy_adapter/core/mtls_proxy.py +0 -80
  121. mcp_proxy_adapter/core/mtls_server.py +3 -173
  122. mcp_proxy_adapter/core/protocol_manager.py +1 -191
  123. mcp_proxy_adapter/core/proxy/__init__.py +22 -0
  124. mcp_proxy_adapter/core/proxy/auth_manager.py +27 -0
  125. mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +137 -0
  126. mcp_proxy_adapter/core/proxy/registration_client.py +60 -0
  127. mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
  128. mcp_proxy_adapter/core/proxy_client.py +0 -1
  129. mcp_proxy_adapter/core/proxy_registration.py +36 -913
  130. mcp_proxy_adapter/core/role_utils.py +0 -308
  131. mcp_proxy_adapter/core/security_adapter.py +1 -36
  132. mcp_proxy_adapter/core/security_factory.py +1 -150
  133. mcp_proxy_adapter/core/security_integration.py +0 -33
  134. mcp_proxy_adapter/core/server_adapter.py +1 -40
  135. mcp_proxy_adapter/core/server_engine.py +2 -173
  136. mcp_proxy_adapter/core/settings.py +0 -127
  137. mcp_proxy_adapter/core/signal_handler.py +0 -65
  138. mcp_proxy_adapter/core/ssl_utils.py +19 -137
  139. mcp_proxy_adapter/core/transport_manager.py +0 -151
  140. mcp_proxy_adapter/core/unified_config_adapter.py +1 -193
  141. mcp_proxy_adapter/core/utils.py +1 -182
  142. mcp_proxy_adapter/core/validation/__init__.py +21 -0
  143. mcp_proxy_adapter/core/validation/config_validator.py +211 -0
  144. mcp_proxy_adapter/core/validation/file_validator.py +73 -0
  145. mcp_proxy_adapter/core/validation/protocol_validator.py +191 -0
  146. mcp_proxy_adapter/core/validation/security_validator.py +58 -0
  147. mcp_proxy_adapter/core/validation/validation_result.py +27 -0
  148. mcp_proxy_adapter/custom_openapi.py +33 -652
  149. mcp_proxy_adapter/examples/bugfix_certificate_config.py +0 -23
  150. mcp_proxy_adapter/examples/check_config.py +0 -2
  151. mcp_proxy_adapter/examples/client_usage_example.py +164 -0
  152. mcp_proxy_adapter/examples/config_builder.py +13 -2
  153. mcp_proxy_adapter/examples/config_cli.py +0 -1
  154. mcp_proxy_adapter/examples/create_test_configs.py +0 -46
  155. mcp_proxy_adapter/examples/debug_request_state.py +0 -1
  156. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -47
  157. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -45
  158. mcp_proxy_adapter/examples/full_application/commands/echo_command.py +0 -12
  159. mcp_proxy_adapter/examples/full_application/commands/help_command.py +0 -12
  160. mcp_proxy_adapter/examples/full_application/commands/list_command.py +0 -7
  161. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -2
  162. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -59
  163. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -54
  164. mcp_proxy_adapter/examples/full_application/main.py +186 -150
  165. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -107
  166. mcp_proxy_adapter/examples/full_application/test_minimal_server.py +0 -24
  167. mcp_proxy_adapter/examples/full_application/test_server.py +0 -58
  168. mcp_proxy_adapter/examples/generate_config.py +65 -11
  169. mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
  170. mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
  171. mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
  172. mcp_proxy_adapter/examples/queue_server_example.py +85 -0
  173. mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
  174. mcp_proxy_adapter/examples/required_certificates.py +0 -2
  175. mcp_proxy_adapter/examples/run_full_test_suite.py +0 -29
  176. mcp_proxy_adapter/examples/run_proxy_server.py +31 -71
  177. mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -27
  178. mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
  179. mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
  180. mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
  181. mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
  182. mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
  183. mcp_proxy_adapter/examples/security_test_client.py +24 -1075
  184. mcp_proxy_adapter/examples/setup/__init__.py +24 -0
  185. mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
  186. mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
  187. mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
  188. mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
  189. mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
  190. mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
  191. mcp_proxy_adapter/examples/setup_test_environment.py +133 -1425
  192. mcp_proxy_adapter/examples/test_config.py +0 -3
  193. mcp_proxy_adapter/examples/test_config_builder.py +25 -405
  194. mcp_proxy_adapter/examples/test_examples.py +0 -1
  195. mcp_proxy_adapter/examples/test_framework_complete.py +0 -2
  196. mcp_proxy_adapter/examples/test_mcp_server.py +0 -1
  197. mcp_proxy_adapter/examples/test_protocol_examples.py +0 -1
  198. mcp_proxy_adapter/examples/universal_client.py +0 -6
  199. mcp_proxy_adapter/examples/update_config_certificates.py +0 -1
  200. mcp_proxy_adapter/examples/validate_generator_compatibility.py +0 -1
  201. mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +0 -187
  202. mcp_proxy_adapter/integrations/__init__.py +25 -0
  203. mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
  204. mcp_proxy_adapter/main.py +70 -62
  205. mcp_proxy_adapter/openapi.py +0 -22
  206. mcp_proxy_adapter/version.py +1 -1
  207. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/METADATA +2 -1
  208. mcp_proxy_adapter-6.9.29.dist-info/RECORD +235 -0
  209. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/entry_points.txt +1 -1
  210. mcp_proxy_adapter-6.9.28.dist-info/RECORD +0 -149
  211. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/WHEEL +0 -0
  212. {mcp_proxy_adapter-6.9.28.dist-info → mcp_proxy_adapter-6.9.29.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,85 @@
1
+ """
2
+ Queue Server Example for MCP Proxy Adapter.
3
+
4
+ This example demonstrates how to run an MCP server with queue integration
5
+ for managing background jobs.
6
+
7
+ Author: Vasiliy Zdanovskiy
8
+ email: vasilyvz@gmail.com
9
+ """
10
+
11
+ import asyncio
12
+ from hypercorn.asyncio import serve
13
+ from hypercorn.config import Config as HyperConfig
14
+ from mcp_proxy_adapter.api.app import create_app
15
+ from mcp_proxy_adapter.commands.command_registry import registry
16
+ from mcp_proxy_adapter.commands.queue_commands import (
17
+ QueueAddJobCommand,
18
+ QueueStartJobCommand,
19
+ QueueStopJobCommand,
20
+ QueueDeleteJobCommand,
21
+ QueueGetJobStatusCommand,
22
+ QueueListJobsCommand,
23
+ QueueHealthCommand,
24
+ )
25
+ from mcp_proxy_adapter.integrations.queuemgr_integration import (
26
+ init_global_queue_manager,
27
+ shutdown_global_queue_manager,
28
+ )
29
+
30
+
31
+ async def setup_queue_commands():
32
+ """Setup queue management commands."""
33
+ print("šŸ”§ Setting up queue management commands...")
34
+
35
+ # Register queue commands
36
+ registry.register(QueueAddJobCommand())
37
+ registry.register(QueueStartJobCommand())
38
+ registry.register(QueueStopJobCommand())
39
+ registry.register(QueueDeleteJobCommand())
40
+ registry.register(QueueGetJobStatusCommand())
41
+ registry.register(QueueListJobsCommand())
42
+ registry.register(QueueHealthCommand())
43
+
44
+ print("āœ… Queue commands registered")
45
+
46
+
47
+ def create_queue_server_app() -> any:
48
+ """Create MCP server application with queue integration."""
49
+ app = create_app()
50
+
51
+ @app.on_event("startup")
52
+ async def _on_startup() -> None:
53
+ await init_global_queue_manager()
54
+ await setup_queue_commands()
55
+
56
+ @app.on_event("shutdown")
57
+ async def _on_shutdown() -> None:
58
+ await shutdown_global_queue_manager()
59
+
60
+ return app
61
+
62
+
63
+ async def main():
64
+ """Main function to run the queue server with Hypercorn."""
65
+ print("šŸš€ Starting MCP Proxy Adapter Queue Server")
66
+ print("=" * 50)
67
+
68
+ app = create_queue_server_app()
69
+
70
+ hc = HyperConfig()
71
+ hc.bind = ["0.0.0.0:8000"]
72
+ hc.loglevel = "info"
73
+
74
+ print("āœ… MCP Queue Server will start at http://localhost:8000")
75
+ print("šŸ“ Example usage:")
76
+ print(" curl -X POST http://localhost:8000/api/jsonrpc \\")
77
+ print(" -H 'Content-Type: application/json' \\")
78
+ print(" -d '{\"jsonrpc\": \"2.0\", \"method\": \"queue_health\", \"params\": {}, \"id\": 1}'")
79
+ print()
80
+
81
+ await serve(app, hc)
82
+
83
+
84
+ if __name__ == "__main__":
85
+ asyncio.run(main())
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple Queue Server for MCP Proxy Adapter.
4
+
5
+ This example demonstrates how to run an MCP server with queue integration
6
+ using a minimal configuration.
7
+
8
+ Author: Vasiliy Zdanovskiy
9
+ email: vasilyvz@gmail.com
10
+ """
11
+
12
+ import asyncio
13
+ import uvicorn
14
+ from mcp_proxy_adapter.api.app import create_app
15
+ from mcp_proxy_adapter.commands.command_registry import registry
16
+ from mcp_proxy_adapter.commands.queue_commands import (
17
+ QueueAddJobCommand,
18
+ QueueStartJobCommand,
19
+ QueueStopJobCommand,
20
+ QueueDeleteJobCommand,
21
+ QueueGetJobStatusCommand,
22
+ QueueListJobsCommand,
23
+ QueueHealthCommand,
24
+ )
25
+
26
+
27
+ def setup_queue_commands():
28
+ """Setup queue management commands."""
29
+ print("šŸ”§ Setting up queue management commands...")
30
+
31
+ # Register queue commands
32
+ registry.register_custom(QueueAddJobCommand())
33
+ registry.register_custom(QueueStartJobCommand())
34
+ registry.register_custom(QueueStopJobCommand())
35
+ registry.register_custom(QueueDeleteJobCommand())
36
+ registry.register_custom(QueueGetJobStatusCommand())
37
+ registry.register_custom(QueueListJobsCommand())
38
+ registry.register_custom(QueueHealthCommand())
39
+
40
+ print("āœ… Queue commands registered")
41
+
42
+
43
+ def create_queue_server_app():
44
+ """Create MCP server application with queue integration."""
45
+ # Create minimal config
46
+ config = {
47
+ "uuid": "123e4567-e89b-42d3-8a56-426614174000",
48
+ "server": {
49
+ "host": "172.28.0.1",
50
+ "port": 8000,
51
+ "protocol": "http",
52
+ "debug": False,
53
+ "log_level": "INFO"
54
+ },
55
+ "logging": {
56
+ "level": "INFO",
57
+ "file": None,
58
+ "log_dir": "./logs",
59
+ "log_file": "mcp_proxy_adapter.log",
60
+ "error_log_file": "mcp_proxy_adapter_error.log",
61
+ "access_log_file": "mcp_proxy_adapter_access.log",
62
+ "max_file_size": "10MB",
63
+ "backup_count": 5,
64
+ "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
65
+ "date_format": "%Y-%m-%d %H:%M:%S",
66
+ "console_output": True,
67
+ "file_output": True
68
+ },
69
+ "commands": {
70
+ "auto_discovery": True,
71
+ "commands_directory": "./commands",
72
+ "catalog_directory": "./catalog",
73
+ "plugin_servers": [],
74
+ "auto_install_dependencies": True,
75
+ "enabled_commands": ["health", "echo", "list", "help"],
76
+ "disabled_commands": [],
77
+ "custom_commands_path": "./commands"
78
+ },
79
+ "transport": {
80
+ "type": "http",
81
+ "port": 8000
82
+ },
83
+ "ssl": {
84
+ "enabled": False
85
+ },
86
+ "proxy_registration": {
87
+ "enabled": True,
88
+ "proxy_url": "https://172.28.0.4:3004",
89
+ "server_id": "mcp_queue_server",
90
+ "server_name": "MCP Queue Server",
91
+ "description": "Queue management server with mTLS",
92
+ "version": "6.9.28",
93
+ "protocol": "mtls",
94
+ "ssl": {
95
+ "enabled": True,
96
+ "verify_ssl": False,
97
+ "verify_hostname": False,
98
+ "verify_mode": "CERT_REQUIRED",
99
+ "ca_cert": "./mtls_certificates/ca/ca.crt",
100
+ "cert_file": "./mtls_certificates/client/test-client.crt",
101
+ "key_file": "./mtls_certificates/client/test-client.key"
102
+ },
103
+ "certificate": {
104
+ "cert_file": "./mtls_certificates/client/test-client.crt",
105
+ "key_file": "./mtls_certificates/client/test-client.key"
106
+ },
107
+ "registration_timeout": 30,
108
+ "retry_attempts": 3,
109
+ "retry_delay": 5,
110
+ "auto_register_on_startup": True,
111
+ "auto_unregister_on_shutdown": True,
112
+ "heartbeat": {
113
+ "enabled": True,
114
+ "interval": 30,
115
+ "timeout": 10,
116
+ "retry_attempts": 3,
117
+ "retry_delay": 5,
118
+ "url": "/heartbeat"
119
+ }
120
+ },
121
+ "debug": {
122
+ "enabled": False,
123
+ "level": "WARNING"
124
+ },
125
+ "security": {
126
+ "enabled": False
127
+ },
128
+ "roles": {
129
+ "enabled": False
130
+ }
131
+ }
132
+
133
+ # Register commands before creating the app
134
+ setup_queue_commands()
135
+
136
+ app = create_app(app_config=config)
137
+
138
+ @app.on_event("startup")
139
+
140
+ @app.on_event("shutdown")
141
+
142
+ return app
143
+
144
+
145
+ async def main():
146
+ """Main function to run the queue server."""
147
+ print("šŸš€ Starting MCP Proxy Adapter Queue Server")
148
+ print("=" * 50)
149
+
150
+ # Create the app
151
+ app = create_queue_server_app()
152
+
153
+ # Run the server
154
+ config = uvicorn.Config(
155
+ app=app,
156
+ host="0.0.0.0",
157
+ port=8000,
158
+ log_level="info"
159
+ )
160
+ server = uvicorn.Server(config)
161
+
162
+ print("āœ… MCP Queue Server started at http://localhost:8000")
163
+ print("šŸ“ Example usage:")
164
+ print(" curl -X POST http://localhost:8000/api/jsonrpc \\")
165
+ print(" -H 'Content-Type: application/json' \\")
166
+ print(" -d '{\"jsonrpc\": \"2.0\", \"method\": \"queue_health\", \"params\": {}, \"id\": 1}'")
167
+ print()
168
+
169
+ await server.serve()
170
+
171
+
172
+ if __name__ == "__main__":
173
+ asyncio.run(main())
@@ -7,8 +7,6 @@ Author: Vasiliy Zdanovskiy
7
7
  email: vasilyvz@gmail.com
8
8
  """
9
9
 
10
- from typing import Dict, List, Any
11
- from pathlib import Path
12
10
 
13
11
  # Base paths
14
12
  CERTS_DIR = Path("certs")
@@ -444,35 +444,6 @@ class FullTestSuiteRunner:
444
444
  # Process cleanup is handled by the test scripts themselves
445
445
  print("āœ… Cleanup completed")
446
446
 
447
- def cleanup_directories(self) -> bool:
448
- """Clean up existing test directories before starting."""
449
- self.print_info("Cleaning up existing test directories...")
450
-
451
- try:
452
- import shutil
453
-
454
- # Directories to clean
455
- dirs_to_clean = [self.configs_dir, self.certs_dir, self.keys_dir]
456
- files_to_clean = [self.working_dir / "roles.json"]
457
-
458
- # Remove directories
459
- for dir_path in dirs_to_clean:
460
- if dir_path.exists():
461
- shutil.rmtree(dir_path)
462
- print(f"šŸ—‘ļø Removed directory: {dir_path}")
463
-
464
- # Remove files
465
- for file_path in files_to_clean:
466
- if file_path.exists():
467
- file_path.unlink()
468
- print(f"šŸ—‘ļø Removed file: {file_path}")
469
-
470
- self.print_success("Directory cleanup completed")
471
- return True
472
-
473
- except Exception as e:
474
- self.print_error(f"Failed to cleanup directories: {e}")
475
- return False
476
447
 
477
448
  def test_all_configurations(self) -> bool:
478
449
  """Test all server configurations including proxy registration."""
@@ -14,13 +14,9 @@ import asyncio
14
14
  import signal
15
15
  import sys
16
16
  from typing import Dict, List, Optional
17
- import json
18
- from datetime import datetime, timedelta
19
17
 
20
18
  from fastapi import FastAPI, HTTPException
21
19
  from pydantic import BaseModel
22
- from mcp_proxy_adapter.core.server_adapter import UnifiedServerRunner
23
-
24
20
 
25
21
  # Simple in-memory storage for registered adapters
26
22
  registered_adapters: Dict[str, Dict] = {}
@@ -42,68 +38,33 @@ class ProxyRouter:
42
38
 
43
39
  def _setup_routes(self):
44
40
  @self.app.post("/register")
45
- async def register_adapter(registration_data: dict):
46
- """Register an adapter with the proxy."""
47
- # Handle adapter format: server_id, server_url, server_name
48
- adapter_id = registration_data["server_id"]
49
- name = registration_data.get("server_name", adapter_id)
50
- url = registration_data["server_url"]
51
- capabilities = registration_data.get("capabilities", [])
52
- metadata = {
53
- "description": registration_data.get("description", ""),
54
- "version": registration_data.get("version", ""),
55
- "endpoints": registration_data.get("endpoints", {})
56
- }
57
-
58
- registered_adapters[adapter_id] = {
59
- "name": name,
60
- "url": url,
61
- "capabilities": capabilities,
62
- "metadata": metadata,
63
- "registered_at": datetime.now().isoformat(),
64
- "last_heartbeat": datetime.now().isoformat(),
65
- "status": "active",
66
- }
67
- print(f"āœ… Registered adapter: {adapter_id} at {url}")
68
- return {"status": "registered", "adapter_id": adapter_id, "success": True}
41
+ def register(adapter: AdapterRegistration): # type: ignore[name-defined]
42
+ registered_adapters[adapter.name] = adapter.dict()
43
+ return {"status": "ok", "registered": adapter.name}
69
44
 
70
45
  @self.app.post("/unregister")
71
- async def unregister_adapter(adapter_id: str):
72
- """Unregister an adapter from the proxy."""
73
- if adapter_id in registered_adapters:
74
- del registered_adapters[adapter_id]
75
- print(f"āœ… Unregistered adapter: {adapter_id}")
76
- return {"status": "unregistered", "adapter_id": adapter_id}
77
- else:
78
- raise HTTPException(status_code=404, detail="Adapter not found")
46
+ def unregister(adapter: AdapterRegistration): # type: ignore[name-defined]
47
+ registered_adapters.pop(adapter.name, None)
48
+ return {"status": "ok", "unregistered": adapter.name}
49
+
50
+ @self.app.post("/proxy/heartbeat")
51
+ def heartbeat(adapter: AdapterRegistration): # type: ignore[name-defined]
52
+ if adapter.name in registered_adapters:
53
+ return {"status": "ok", "heartbeat": adapter.name}
54
+ raise HTTPException(status_code=404, detail="Adapter not registered")
79
55
 
80
56
  @self.app.get("/proxy/list")
81
- async def list_adapters():
82
- """List all registered adapters."""
83
- return {
84
- "adapters": list(registered_adapters.values()),
85
- "count": len(registered_adapters),
86
- }
57
+ def list_registered():
58
+ return {"servers": list(registered_adapters.values())}
87
59
 
88
60
  @self.app.get("/proxy/health")
89
- async def health_check():
90
- """Health check endpoint."""
91
- return {
92
- "status": "healthy",
93
- "timestamp": datetime.now().isoformat(),
94
- "adapters_count": len(registered_adapters),
95
- }
61
+ def proxy_health():
62
+ return {"status": "ok", "model": "mcp-local-proxy", "version": "1.0.0"}
96
63
 
97
- @self.app.post("/proxy/heartbeat")
98
- async def heartbeat(adapter_id: str):
99
- """Receive heartbeat from adapter."""
100
- if adapter_id in registered_adapters:
101
- registered_adapters[adapter_id][
102
- "last_heartbeat"
103
- ] = datetime.now().isoformat()
104
- return {"status": "ok", "adapter_id": adapter_id}
105
- else:
106
- raise HTTPException(status_code=404, detail="Adapter not found")
64
+ # Compatibility endpoint expected by test instructions
65
+ @self.app.get("/servers")
66
+ def servers_plain():
67
+ return list(registered_adapters.values())
107
68
 
108
69
 
109
70
  def create_proxy_app() -> FastAPI:
@@ -135,8 +96,8 @@ def main() -> None:
135
96
  app = create_proxy_app()
136
97
 
137
98
  # Setup graceful shutdown
138
- def signal_handler(signum, frame):
139
- print("\nšŸ›‘ Shutting down proxy server...")
99
+ def signal_handler(signum, frame): # type: ignore[no-redef]
100
+ print("\nšŸ›‘ Proxy server stopping...")
140
101
  sys.exit(0)
141
102
 
142
103
  signal.signal(signal.SIGINT, signal_handler)
@@ -153,16 +114,15 @@ def main() -> None:
153
114
  print(" POST /proxy/heartbeat - Heartbeat from adapter")
154
115
  print("⚔ Press Ctrl+C to stop\n")
155
116
 
156
- # Run server via unified runner (hypercorn under the hood)
157
- runner = UnifiedServerRunner()
158
- runner.run_server(
159
- app,
160
- {
161
- "host": args.host,
162
- "port": args.port,
163
- "log_level": args.log_level,
164
- },
165
- )
117
+ # Run server with Hypercorn
118
+ from hypercorn.asyncio import serve
119
+ from hypercorn.config import Config
120
+
121
+ config = Config()
122
+ config.bind = [f"{args.host}:{args.port}"]
123
+ config.loglevel = args.log_level
124
+
125
+ asyncio.run(serve(app, config))
166
126
 
167
127
 
168
128
  if __name__ == "__main__":
@@ -9,12 +9,10 @@ email: vasilyvz@gmail.com
9
9
  import asyncio
10
10
  import json
11
11
  import os
12
- import signal
13
12
  import subprocess
14
13
  import sys
15
14
  import time
16
15
  from pathlib import Path
17
- from typing import Dict, List, Optional, Tuple
18
16
 
19
17
  # Add project root to path
20
18
  project_root = Path(__file__).parent.parent.parent
@@ -404,31 +402,6 @@ class SecurityTestRunner:
404
402
 
405
403
  return passed_tests == total_tests
406
404
 
407
- def print_summary(self):
408
- """Print test summary."""
409
- if not self.test_results:
410
- print("šŸ“Š No test results to display")
411
- return
412
-
413
- total_tests = len(self.test_results)
414
- passed_tests = sum(1 for result in self.test_results if result.success)
415
-
416
- print("\n" + "=" * 50)
417
- print("šŸ“Š TEST SUMMARY")
418
- print("=" * 50)
419
- print(f"Total tests: {total_tests}")
420
- print(f"Passed: {passed_tests}")
421
- print(f"Failed: {total_tests - passed_tests}")
422
- print(f"Success rate: {(passed_tests/total_tests)*100:.1f}%")
423
-
424
- if total_tests - passed_tests > 0:
425
- print(f"\nšŸ“‹ DETAILED RESULTS")
426
- print("-" * 30)
427
- for result in self.test_results:
428
- status = "āœ… PASS" if result.success else "āŒ FAIL"
429
- print(f"{status} {result.test_name}")
430
- if not result.success and result.error_message:
431
- print(f" Error: {result.error_message}")
432
405
 
433
406
 
434
407
  async def main():
@@ -0,0 +1,18 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Security test package for MCP Proxy Adapter.
6
+ """
7
+
8
+ from .test_result import TestResult
9
+ from .ssl_context_manager import SSLContextManager
10
+ from .auth_manager import AuthManager
11
+ from .test_client import SecurityTestClient
12
+
13
+ __all__ = [
14
+ "TestResult",
15
+ "SSLContextManager",
16
+ "AuthManager",
17
+ "SecurityTestClient",
18
+ ]
@@ -0,0 +1,14 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ Authentication manager for security testing.
6
+ """
7
+
8
+ import base64
9
+ from typing import Dict
10
+
11
+
12
+ class AuthManager:
13
+ """Manager for authentication in security testing."""
14
+
@@ -0,0 +1,28 @@
1
+ """
2
+ Author: Vasiliy Zdanovskiy
3
+ email: vasilyvz@gmail.com
4
+
5
+ SSL context manager for security testing.
6
+ """
7
+
8
+ import os
9
+ import ssl
10
+ from pathlib import Path
11
+ from typing import Optional
12
+
13
+
14
+ class SSLContextManager:
15
+ """Manager for SSL contexts in security testing."""
16
+
17
+ def __init__(self, project_root: Optional[Path] = None):
18
+ """
19
+ Initialize SSL context manager.
20
+
21
+ Args:
22
+ project_root: Root directory of the project (optional)
23
+ """
24
+ if project_root is None:
25
+ project_root = Path(__file__).parent.parent.parent.parent
26
+ self.project_root = project_root
27
+
28
+