mcp-proxy-adapter 4.1.1__py3-none-any.whl → 6.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. mcp_proxy_adapter/__main__.py +12 -0
  2. mcp_proxy_adapter/api/app.py +254 -33
  3. mcp_proxy_adapter/api/handlers.py +32 -6
  4. mcp_proxy_adapter/api/middleware/__init__.py +36 -30
  5. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
  6. mcp_proxy_adapter/api/middleware/error_handling.py +9 -0
  7. mcp_proxy_adapter/api/middleware/factory.py +243 -0
  8. mcp_proxy_adapter/api/middleware/logging.py +32 -6
  9. mcp_proxy_adapter/api/middleware/protocol_middleware.py +135 -0
  10. mcp_proxy_adapter/api/middleware/transport_middleware.py +122 -0
  11. mcp_proxy_adapter/api/middleware/unified_security.py +152 -0
  12. mcp_proxy_adapter/api/middleware/user_info_middleware.py +83 -0
  13. mcp_proxy_adapter/commands/__init__.py +19 -4
  14. mcp_proxy_adapter/commands/auth_validation_command.py +408 -0
  15. mcp_proxy_adapter/commands/base.py +66 -32
  16. mcp_proxy_adapter/commands/builtin_commands.py +95 -0
  17. mcp_proxy_adapter/commands/catalog_manager.py +838 -0
  18. mcp_proxy_adapter/commands/cert_monitor_command.py +620 -0
  19. mcp_proxy_adapter/commands/certificate_management_command.py +608 -0
  20. mcp_proxy_adapter/commands/command_registry.py +711 -354
  21. mcp_proxy_adapter/commands/dependency_manager.py +245 -0
  22. mcp_proxy_adapter/commands/echo_command.py +81 -0
  23. mcp_proxy_adapter/commands/health_command.py +7 -0
  24. mcp_proxy_adapter/commands/help_command.py +21 -14
  25. mcp_proxy_adapter/commands/hooks.py +200 -167
  26. mcp_proxy_adapter/commands/key_management_command.py +506 -0
  27. mcp_proxy_adapter/commands/load_command.py +176 -0
  28. mcp_proxy_adapter/commands/plugins_command.py +235 -0
  29. mcp_proxy_adapter/commands/protocol_management_command.py +232 -0
  30. mcp_proxy_adapter/commands/proxy_registration_command.py +409 -0
  31. mcp_proxy_adapter/commands/reload_command.py +48 -50
  32. mcp_proxy_adapter/commands/result.py +1 -0
  33. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  34. mcp_proxy_adapter/commands/roles_management_command.py +697 -0
  35. mcp_proxy_adapter/commands/security_command.py +488 -0
  36. mcp_proxy_adapter/commands/ssl_setup_command.py +483 -0
  37. mcp_proxy_adapter/commands/token_management_command.py +529 -0
  38. mcp_proxy_adapter/commands/transport_management_command.py +144 -0
  39. mcp_proxy_adapter/commands/unload_command.py +158 -0
  40. mcp_proxy_adapter/config.py +159 -2
  41. mcp_proxy_adapter/core/app_factory.py +326 -0
  42. mcp_proxy_adapter/core/auth_validator.py +606 -0
  43. mcp_proxy_adapter/core/certificate_utils.py +827 -0
  44. mcp_proxy_adapter/core/client_security.py +384 -0
  45. mcp_proxy_adapter/core/config_converter.py +405 -0
  46. mcp_proxy_adapter/core/config_validator.py +218 -0
  47. mcp_proxy_adapter/core/logging.py +19 -3
  48. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  49. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  50. mcp_proxy_adapter/core/protocol_manager.py +235 -0
  51. mcp_proxy_adapter/core/proxy_client.py +602 -0
  52. mcp_proxy_adapter/core/proxy_registration.py +522 -0
  53. mcp_proxy_adapter/core/role_utils.py +426 -0
  54. mcp_proxy_adapter/core/security_adapter.py +370 -0
  55. mcp_proxy_adapter/core/security_factory.py +239 -0
  56. mcp_proxy_adapter/core/security_integration.py +277 -0
  57. mcp_proxy_adapter/core/server_adapter.py +345 -0
  58. mcp_proxy_adapter/core/server_engine.py +364 -0
  59. mcp_proxy_adapter/core/settings.py +1 -0
  60. mcp_proxy_adapter/core/ssl_utils.py +233 -0
  61. mcp_proxy_adapter/core/transport_manager.py +292 -0
  62. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  63. mcp_proxy_adapter/custom_openapi.py +22 -11
  64. mcp_proxy_adapter/examples/README.md +230 -97
  65. mcp_proxy_adapter/examples/README_EN.md +258 -0
  66. mcp_proxy_adapter/examples/SECURITY_TESTING.md +455 -0
  67. mcp_proxy_adapter/examples/__pycache__/security_configurations.cpython-312.pyc +0 -0
  68. mcp_proxy_adapter/examples/__pycache__/security_test_client.cpython-312.pyc +0 -0
  69. mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +37 -0
  70. mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +23 -0
  71. mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +39 -0
  72. mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +25 -0
  73. mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +39 -0
  74. mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +45 -0
  75. mcp_proxy_adapter/examples/basic_framework/main.py +63 -0
  76. mcp_proxy_adapter/examples/basic_framework/roles.json +21 -0
  77. mcp_proxy_adapter/examples/cert_config.json +9 -0
  78. mcp_proxy_adapter/examples/certs/admin.crt +32 -0
  79. mcp_proxy_adapter/examples/certs/admin.key +52 -0
  80. mcp_proxy_adapter/examples/certs/admin_cert.pem +21 -0
  81. mcp_proxy_adapter/examples/certs/admin_key.pem +28 -0
  82. mcp_proxy_adapter/examples/certs/ca_cert.pem +23 -0
  83. mcp_proxy_adapter/examples/certs/ca_cert.srl +1 -0
  84. mcp_proxy_adapter/examples/certs/ca_key.pem +28 -0
  85. mcp_proxy_adapter/examples/certs/cert_config.json +9 -0
  86. mcp_proxy_adapter/examples/certs/client.crt +32 -0
  87. mcp_proxy_adapter/examples/certs/client.key +52 -0
  88. mcp_proxy_adapter/examples/certs/client_admin.crt +32 -0
  89. mcp_proxy_adapter/examples/certs/client_admin.key +52 -0
  90. mcp_proxy_adapter/examples/certs/client_user.crt +32 -0
  91. mcp_proxy_adapter/examples/certs/client_user.key +52 -0
  92. mcp_proxy_adapter/examples/certs/guest_cert.pem +21 -0
  93. mcp_proxy_adapter/examples/certs/guest_key.pem +28 -0
  94. mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +23 -0
  95. mcp_proxy_adapter/examples/certs/proxy_cert.pem +21 -0
  96. mcp_proxy_adapter/examples/certs/proxy_key.pem +28 -0
  97. mcp_proxy_adapter/examples/certs/readonly.crt +32 -0
  98. mcp_proxy_adapter/examples/certs/readonly.key +52 -0
  99. mcp_proxy_adapter/examples/certs/readonly_cert.pem +21 -0
  100. mcp_proxy_adapter/examples/certs/readonly_key.pem +28 -0
  101. mcp_proxy_adapter/examples/certs/server.crt +32 -0
  102. mcp_proxy_adapter/examples/certs/server.key +52 -0
  103. mcp_proxy_adapter/examples/certs/server_cert.pem +32 -0
  104. mcp_proxy_adapter/examples/certs/server_key.pem +52 -0
  105. mcp_proxy_adapter/examples/certs/test_ca_ca.crt +20 -0
  106. mcp_proxy_adapter/examples/certs/user.crt +32 -0
  107. mcp_proxy_adapter/examples/certs/user.key +52 -0
  108. mcp_proxy_adapter/examples/certs/user_cert.pem +21 -0
  109. mcp_proxy_adapter/examples/certs/user_key.pem +28 -0
  110. mcp_proxy_adapter/examples/client_configs/api_key_client.json +13 -0
  111. mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +13 -0
  112. mcp_proxy_adapter/examples/client_configs/certificate_client.json +22 -0
  113. mcp_proxy_adapter/examples/client_configs/jwt_client.json +15 -0
  114. mcp_proxy_adapter/examples/client_configs/no_auth_client.json +9 -0
  115. mcp_proxy_adapter/examples/commands/__init__.py +1 -0
  116. mcp_proxy_adapter/examples/create_certificates_simple.py +307 -0
  117. mcp_proxy_adapter/examples/debug_request_state.py +144 -0
  118. mcp_proxy_adapter/examples/debug_role_chain.py +205 -0
  119. mcp_proxy_adapter/examples/demo_client.py +341 -0
  120. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +99 -0
  121. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +106 -0
  122. mcp_proxy_adapter/examples/full_application/configs/http_auth.json +37 -0
  123. mcp_proxy_adapter/examples/full_application/configs/http_simple.json +23 -0
  124. mcp_proxy_adapter/examples/full_application/configs/https_auth.json +39 -0
  125. mcp_proxy_adapter/examples/full_application/configs/https_simple.json +25 -0
  126. mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +39 -0
  127. mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +45 -0
  128. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +97 -0
  129. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +95 -0
  130. mcp_proxy_adapter/examples/full_application/main.py +138 -0
  131. mcp_proxy_adapter/examples/full_application/roles.json +21 -0
  132. mcp_proxy_adapter/examples/generate_all_certificates.py +429 -0
  133. mcp_proxy_adapter/examples/generate_certificates.py +121 -0
  134. mcp_proxy_adapter/examples/keys/ca_key.pem +28 -0
  135. mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +28 -0
  136. mcp_proxy_adapter/examples/keys/test_ca_ca.key +28 -0
  137. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +220 -0
  138. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +1 -0
  139. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +1 -0
  140. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +1 -0
  141. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +1 -0
  142. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +1 -0
  143. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +220 -0
  144. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +1 -0
  145. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +1 -0
  146. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +1 -0
  147. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +1 -0
  148. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +1 -0
  149. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +2 -0
  150. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +1 -0
  151. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +1 -0
  152. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +1 -0
  153. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +1 -0
  154. mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +1 -0
  155. mcp_proxy_adapter/examples/proxy_registration_example.py +401 -0
  156. mcp_proxy_adapter/examples/roles.json +38 -0
  157. mcp_proxy_adapter/examples/run_example.py +81 -0
  158. mcp_proxy_adapter/examples/run_security_tests.py +326 -0
  159. mcp_proxy_adapter/examples/run_security_tests_fixed.py +300 -0
  160. mcp_proxy_adapter/examples/security_test_client.py +743 -0
  161. mcp_proxy_adapter/examples/server_configs/config_basic_http.json +204 -0
  162. mcp_proxy_adapter/examples/server_configs/config_http_token.json +238 -0
  163. mcp_proxy_adapter/examples/server_configs/config_https.json +215 -0
  164. mcp_proxy_adapter/examples/server_configs/config_https_token.json +231 -0
  165. mcp_proxy_adapter/examples/server_configs/config_mtls.json +215 -0
  166. mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +250 -0
  167. mcp_proxy_adapter/examples/server_configs/config_simple.json +46 -0
  168. mcp_proxy_adapter/examples/server_configs/roles.json +38 -0
  169. mcp_proxy_adapter/examples/test_examples.py +344 -0
  170. mcp_proxy_adapter/examples/universal_client.py +628 -0
  171. mcp_proxy_adapter/main.py +186 -0
  172. mcp_proxy_adapter/utils/config_generator.py +639 -0
  173. mcp_proxy_adapter/version.py +2 -1
  174. mcp_proxy_adapter-6.1.0.dist-info/METADATA +205 -0
  175. mcp_proxy_adapter-6.1.0.dist-info/RECORD +193 -0
  176. mcp_proxy_adapter-6.1.0.dist-info/entry_points.txt +2 -0
  177. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/licenses/LICENSE +2 -2
  178. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  179. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  180. mcp_proxy_adapter/commands/reload_settings_command.py +0 -125
  181. mcp_proxy_adapter/examples/__init__.py +0 -7
  182. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  183. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  184. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  185. mcp_proxy_adapter/examples/basic_server/config.json +0 -35
  186. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  187. mcp_proxy_adapter/examples/basic_server/server.py +0 -103
  188. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  189. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  190. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -250
  191. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  192. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  193. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  194. mcp_proxy_adapter/examples/custom_commands/config.json +0 -35
  195. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  196. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  197. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  198. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  199. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  200. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  201. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  202. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  203. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  204. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  205. mcp_proxy_adapter/examples/custom_commands/server.py +0 -228
  206. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  207. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  208. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  209. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  210. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  211. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  212. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  213. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  214. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  215. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  216. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  217. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  218. mcp_proxy_adapter/tests/__init__.py +0 -0
  219. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  220. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  221. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  222. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  223. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  224. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  225. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  226. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  227. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  228. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  229. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  230. mcp_proxy_adapter/tests/conftest.py +0 -131
  231. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  232. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  233. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  234. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  235. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  236. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  237. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  238. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  239. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  240. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  241. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  242. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  243. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  244. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  245. mcp_proxy_adapter/tests/test_config.py +0 -127
  246. mcp_proxy_adapter/tests/test_utils.py +0 -65
  247. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  248. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  249. mcp_proxy_adapter/tests/unit/test_config.py +0 -217
  250. mcp_proxy_adapter-4.1.1.dist-info/METADATA +0 -200
  251. mcp_proxy_adapter-4.1.1.dist-info/RECORD +0 -110
  252. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/WHEEL +0 -0
  253. {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.1.0.dist-info}/top_level.txt +0 -0
@@ -1,152 +0,0 @@
1
- """
2
- Middleware for rate limiting.
3
- """
4
-
5
- import time
6
- from typing import Dict, List, Callable, Awaitable
7
- from collections import defaultdict
8
-
9
- from fastapi import Request, Response
10
- from starlette.responses import JSONResponse
11
-
12
- from mcp_proxy_adapter.core.logging import logger
13
- from .base import BaseMiddleware
14
-
15
- class RateLimitMiddleware(BaseMiddleware):
16
- """
17
- Middleware for limiting request rate.
18
- """
19
-
20
- def __init__(self, app, rate_limit: int = 100, time_window: int = 60,
21
- by_ip: bool = True, by_user: bool = True,
22
- public_paths: List[str] = None):
23
- """
24
- Initializes middleware for rate limiting.
25
-
26
- Args:
27
- app: FastAPI application
28
- rate_limit: Maximum number of requests in the specified time period
29
- time_window: Time period in seconds
30
- by_ip: Limit requests by IP address
31
- by_user: Limit requests by user
32
- public_paths: List of paths for which rate limiting is not applied
33
- """
34
- super().__init__(app)
35
- self.rate_limit = rate_limit
36
- self.time_window = time_window
37
- self.by_ip = by_ip
38
- self.by_user = by_user
39
- self.public_paths = public_paths or [
40
- "/docs",
41
- "/redoc",
42
- "/openapi.json",
43
- "/health"
44
- ]
45
-
46
- # Storage for requests by IP
47
- self.ip_requests = defaultdict(list)
48
-
49
- # Storage for requests by user
50
- self.user_requests = defaultdict(list)
51
-
52
- async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
53
- """
54
- Processes request and checks rate limit.
55
-
56
- Args:
57
- request: Request.
58
- call_next: Next handler.
59
-
60
- Returns:
61
- Response.
62
- """
63
- # Check if path is public
64
- path = request.url.path
65
- if self._is_public_path(path):
66
- # If path is public, skip rate limiting
67
- return await call_next(request)
68
-
69
- # Current time
70
- current_time = time.time()
71
-
72
- # Get client IP address
73
- client_ip = request.client.host if request.client else "unknown"
74
-
75
- # Get user from request state (if any)
76
- username = getattr(request.state, "username", None)
77
-
78
- # Check limit by IP
79
- if self.by_ip and client_ip != "unknown":
80
- # Clean old requests
81
- self._clean_old_requests(self.ip_requests[client_ip], current_time)
82
-
83
- # Check number of requests
84
- if len(self.ip_requests[client_ip]) >= self.rate_limit:
85
- logger.warning(f"Rate limit exceeded for IP: {client_ip} | Path: {path}")
86
- return self._create_error_response("Rate limit exceeded", 429)
87
-
88
- # Add current request
89
- self.ip_requests[client_ip].append(current_time)
90
-
91
- # Check limit by user
92
- if self.by_user and username:
93
- # Clean old requests
94
- self._clean_old_requests(self.user_requests[username], current_time)
95
-
96
- # Check number of requests
97
- if len(self.user_requests[username]) >= self.rate_limit:
98
- logger.warning(f"Rate limit exceeded for user: {username} | Path: {path}")
99
- return self._create_error_response("Rate limit exceeded", 429)
100
-
101
- # Add current request
102
- self.user_requests[username].append(current_time)
103
-
104
- # Call the next middleware or main handler
105
- return await call_next(request)
106
-
107
- def _clean_old_requests(self, requests: List[float], current_time: float) -> None:
108
- """
109
- Cleans old requests that are outside the time window.
110
-
111
- Args:
112
- requests: List of request timestamps.
113
- current_time: Current time.
114
- """
115
- min_time = current_time - self.time_window
116
- while requests and requests[0] < min_time:
117
- requests.pop(0)
118
-
119
- def _is_public_path(self, path: str) -> bool:
120
- """
121
- Checks if the path is public.
122
-
123
- Args:
124
- path: Path to check.
125
-
126
- Returns:
127
- True if path is public, False otherwise.
128
- """
129
- return any(path.startswith(public_path) for public_path in self.public_paths)
130
-
131
- def _create_error_response(self, message: str, status_code: int) -> Response:
132
- """
133
- Creates error response in JSON-RPC format.
134
-
135
- Args:
136
- message: Error message.
137
- status_code: HTTP status code.
138
-
139
- Returns:
140
- JSON response with error.
141
- """
142
- return JSONResponse(
143
- status_code=status_code,
144
- content={
145
- "jsonrpc": "2.0",
146
- "error": {
147
- "code": -32000,
148
- "message": message
149
- },
150
- "id": None
151
- }
152
- )
@@ -1,125 +0,0 @@
1
- """
2
- Reload Settings Command
3
-
4
- This command allows reloading configuration settings from files and environment variables.
5
- """
6
-
7
- from typing import Dict, Any
8
- from mcp_proxy_adapter.commands.base import Command
9
- from mcp_proxy_adapter.core.settings import reload_settings, get_custom_settings
10
- from mcp_proxy_adapter.core.logging import get_logger
11
-
12
-
13
- class ReloadSettingsResult:
14
- """
15
- Result class for reload settings command.
16
- """
17
-
18
- def __init__(
19
- self,
20
- success: bool,
21
- message: str,
22
- custom_settings: Dict[str, Any] = None,
23
- error_message: str = None
24
- ):
25
- self.success = success
26
- self.message = message
27
- self.custom_settings = custom_settings or {}
28
- self.error_message = error_message
29
-
30
- def to_dict(self) -> Dict[str, Any]:
31
- """Convert result to dictionary."""
32
- result = {
33
- "success": self.success,
34
- "message": self.message,
35
- "custom_settings": self.custom_settings
36
- }
37
- if self.error_message:
38
- result["error_message"] = self.error_message
39
- return result
40
-
41
- def get_schema(self) -> Dict[str, Any]:
42
- """Get JSON schema for the result."""
43
- return {
44
- "type": "object",
45
- "properties": {
46
- "success": {
47
- "type": "boolean",
48
- "description": "Whether the operation was successful"
49
- },
50
- "message": {
51
- "type": "string",
52
- "description": "Operation result message"
53
- },
54
- "custom_settings": {
55
- "type": "object",
56
- "description": "Current custom settings after reload",
57
- "additionalProperties": True
58
- },
59
- "error_message": {
60
- "type": "string",
61
- "description": "Error message if operation failed"
62
- }
63
- },
64
- "required": ["success", "message", "custom_settings"]
65
- }
66
-
67
-
68
- class ReloadSettingsCommand(Command):
69
- """
70
- Command to reload configuration settings.
71
- """
72
-
73
- name = "reload_settings"
74
- description = "Reload configuration settings from files and environment variables"
75
-
76
- async def execute(self, **params) -> ReloadSettingsResult:
77
- """
78
- Execute the reload settings command.
79
-
80
- Args:
81
- **params: Command parameters (not used)
82
-
83
- Returns:
84
- ReloadSettingsResult with operation status
85
- """
86
- logger = get_logger("reload_settings_command")
87
-
88
- try:
89
- logger.info("šŸ”„ Starting settings reload...")
90
-
91
- # Reload configuration from files and environment variables
92
- reload_settings()
93
-
94
- # Get current custom settings
95
- custom_settings = get_custom_settings()
96
-
97
- logger.info("āœ… Settings reloaded successfully")
98
- logger.info(f"šŸ“‹ Current custom settings: {custom_settings}")
99
-
100
- return ReloadSettingsResult(
101
- success=True,
102
- message="Settings reloaded successfully from configuration files and environment variables",
103
- custom_settings=custom_settings
104
- )
105
-
106
- except Exception as e:
107
- error_msg = f"Failed to reload settings: {str(e)}"
108
- logger.error(f"āŒ {error_msg}")
109
-
110
- return ReloadSettingsResult(
111
- success=False,
112
- message="Failed to reload settings",
113
- custom_settings=get_custom_settings(),
114
- error_message=error_msg
115
- )
116
-
117
- @classmethod
118
- def get_schema(cls) -> Dict[str, Any]:
119
- """Get JSON schema for the command parameters."""
120
- return {
121
- "type": "object",
122
- "description": "Reload configuration settings from files and environment variables",
123
- "properties": {},
124
- "additionalProperties": False
125
- }
@@ -1,7 +0,0 @@
1
- """
2
- MCP Proxy Adapter Examples
3
-
4
- This package contains examples and templates for using the MCP Proxy Adapter framework.
5
- """
6
-
7
- __version__ = "1.0.0"
@@ -1,60 +0,0 @@
1
- # Basic Server Example
2
-
3
- A minimal example of MCP Proxy Adapter server without additional commands.
4
-
5
- ## Features
6
-
7
- This example demonstrates:
8
- - Basic server setup
9
- - Built-in commands only (help, health)
10
- - Default configuration
11
- - No custom commands
12
-
13
- ## Available Commands
14
-
15
- - `help` - Get information about available commands
16
- - `health` - Get server health status
17
-
18
- ## Usage
19
-
20
- ### Run the server
21
-
22
- ```bash
23
- python server.py
24
- ```
25
-
26
- ### Test the server
27
-
28
- ```bash
29
- # Get help
30
- curl -X POST http://localhost:8000/cmd \
31
- -H "Content-Type: application/json" \
32
- -d '{"command": "help"}'
33
-
34
- # Get health status
35
- curl -X POST http://localhost:8000/cmd \
36
- -H "Content-Type: application/json" \
37
- -d '{"command": "health"}'
38
- ```
39
-
40
- ## API Endpoints
41
-
42
- - `POST /cmd` - Execute commands
43
- - `GET /health` - Health check
44
- - `GET /commands` - List available commands
45
- - `GET /docs` - API documentation
46
-
47
- ## Configuration
48
-
49
- The server uses default configuration. You can customize it by:
50
-
51
- 1. Creating a `config.json` file
52
- 2. Setting environment variables
53
- 3. Passing configuration to `create_app()`
54
-
55
- ## Notes
56
-
57
- - This is the simplest possible setup
58
- - No custom commands are registered
59
- - Uses framework defaults
60
- - Good starting point for understanding the framework
@@ -1,7 +0,0 @@
1
- """
2
- Basic Server Example
3
-
4
- A minimal example of MCP Proxy Adapter server without additional commands.
5
- """
6
-
7
- __version__ = "1.0.0"
@@ -1,39 +0,0 @@
1
- {
2
- "application": {
3
- "name": "Basic MCP Proxy Server with Custom Settings",
4
- "version": "1.1.0",
5
- "environment": "development",
6
- "description": "Basic server demonstrating custom settings usage"
7
- },
8
- "features": {
9
- "basic_logging": true,
10
- "simple_commands": true,
11
- "custom_settings_demo": true,
12
- "file_based_config": true
13
- },
14
- "server_info": {
15
- "description": "Basic server with file-based custom settings",
16
- "author": "MCP Proxy Adapter Team",
17
- "contact": "support@example.com",
18
- "documentation": "https://example.com/docs"
19
- },
20
- "demo_settings": {
21
- "welcome_message": "Welcome to Basic MCP Proxy Server with Custom Settings!",
22
- "max_connections": 150,
23
- "timeout": 45,
24
- "debug_mode": true,
25
- "log_level": "INFO"
26
- },
27
- "performance": {
28
- "enable_caching": true,
29
- "cache_ttl": 300,
30
- "max_cache_size": 1000
31
- },
32
- "security": {
33
- "enable_rate_limiting": false,
34
- "max_request_size": "5MB",
35
- "allowed_origins": [
36
- "*"
37
- ]
38
- }
39
- }
@@ -1,35 +0,0 @@
1
- {
2
- "server": {
3
- "host": "127.0.0.1",
4
- "port": 8000,
5
- "debug": true,
6
- "log_level": "DEBUG"
7
- },
8
- "logging": {
9
- "level": "DEBUG",
10
- "log_dir": "./logs/basic_server",
11
- "log_file": "basic_server.log",
12
- "error_log_file": "basic_server_error.log",
13
- "access_log_file": "basic_server_access.log",
14
- "max_file_size": "5MB",
15
- "backup_count": 3,
16
- "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
17
- "date_format": "%Y-%m-%d %H:%M:%S",
18
- "console_output": true,
19
- "file_output": true
20
- },
21
- "commands": {
22
- "auto_discovery": true,
23
- "discovery_path": "mcp_proxy_adapter.commands",
24
- "custom_commands_path": null
25
- },
26
- "custom": {
27
- "server_name": "Basic MCP Proxy Server",
28
- "description": "Simple example server with basic configuration",
29
- "features": {
30
- "hooks_enabled": false,
31
- "custom_commands_enabled": false,
32
- "advanced_logging": false
33
- }
34
- }
35
- }
@@ -1,238 +0,0 @@
1
- """
2
- Custom Settings Example for Basic Server
3
-
4
- This example demonstrates how to use custom settings in a basic server.
5
- """
6
-
7
- import json
8
- import os
9
- from mcp_proxy_adapter.core.settings import (
10
- add_custom_settings,
11
- get_custom_setting_value,
12
- set_custom_setting_value,
13
- get_custom_settings
14
- )
15
- from mcp_proxy_adapter.core.logging import get_logger
16
-
17
-
18
- def setup_basic_custom_settings():
19
- """
20
- Setup basic custom settings for the basic server example.
21
-
22
- This demonstrates how to add custom settings to the framework
23
- and access them throughout the application.
24
- """
25
- logger = get_logger("basic_server_custom_settings")
26
-
27
- # Define basic custom settings
28
- basic_settings = {
29
- "application": {
30
- "name": "Basic MCP Proxy Server",
31
- "version": "1.0.0",
32
- "environment": "development"
33
- },
34
- "features": {
35
- "basic_logging": True,
36
- "simple_commands": True,
37
- "custom_settings_demo": True
38
- },
39
- "server_info": {
40
- "description": "Basic server with custom settings example",
41
- "author": "MCP Proxy Adapter Team",
42
- "contact": "support@example.com"
43
- },
44
- "demo_settings": {
45
- "welcome_message": "Welcome to Basic MCP Proxy Server!",
46
- "max_connections": 100,
47
- "timeout": 30,
48
- "debug_mode": True
49
- }
50
- }
51
-
52
- # Add settings to the framework
53
- add_custom_settings(basic_settings)
54
-
55
- logger.info("āœ… Basic custom settings loaded")
56
- logger.info(f"šŸ“‹ Application: {basic_settings['application']['name']} v{basic_settings['application']['version']}")
57
- logger.info(f"šŸ”§ Features: {list(basic_settings['features'].keys())}")
58
-
59
- return basic_settings
60
-
61
-
62
- def demonstrate_custom_settings_usage():
63
- """
64
- Demonstrate how to use custom settings in the application.
65
- """
66
- logger = get_logger("basic_server_custom_settings")
67
-
68
- # Get specific settings
69
- app_name = get_custom_setting_value("application.name", "Unknown")
70
- app_version = get_custom_setting_value("application.version", "0.0.0")
71
- welcome_msg = get_custom_setting_value("demo_settings.welcome_message", "Hello!")
72
- max_connections = get_custom_setting_value("demo_settings.max_connections", 50)
73
-
74
- logger.info(f"šŸ·ļø Application: {app_name} v{app_version}")
75
- logger.info(f"šŸ’¬ Welcome Message: {welcome_msg}")
76
- logger.info(f"šŸ”— Max Connections: {max_connections}")
77
-
78
- # Check if features are enabled
79
- features = get_custom_setting_value("features", {})
80
- enabled_features = [name for name, enabled in features.items() if enabled]
81
-
82
- logger.info(f"āœ… Enabled Features: {', '.join(enabled_features)}")
83
-
84
- # Set a new custom setting
85
- set_custom_setting_value("demo_settings.last_updated", "2025-08-08")
86
- logger.info("šŸ”§ Set new custom setting: demo_settings.last_updated")
87
-
88
- # Get all custom settings
89
- all_custom_settings = get_custom_settings()
90
- logger.info(f"šŸ“Š Total custom settings: {len(all_custom_settings)} sections")
91
-
92
- return {
93
- "app_name": app_name,
94
- "app_version": app_version,
95
- "welcome_message": welcome_msg,
96
- "max_connections": max_connections,
97
- "enabled_features": enabled_features,
98
- "total_settings_sections": len(all_custom_settings)
99
- }
100
-
101
-
102
- def create_custom_settings_file():
103
- """
104
- Create a custom settings JSON file for the basic server.
105
- """
106
- custom_settings = {
107
- "application": {
108
- "name": "Basic MCP Proxy Server with Custom Settings",
109
- "version": "1.1.0",
110
- "environment": "development",
111
- "description": "Basic server demonstrating custom settings usage"
112
- },
113
- "features": {
114
- "basic_logging": True,
115
- "simple_commands": True,
116
- "custom_settings_demo": True,
117
- "file_based_config": True
118
- },
119
- "server_info": {
120
- "description": "Basic server with file-based custom settings",
121
- "author": "MCP Proxy Adapter Team",
122
- "contact": "support@example.com",
123
- "documentation": "https://example.com/docs"
124
- },
125
- "demo_settings": {
126
- "welcome_message": "Welcome to Basic MCP Proxy Server with Custom Settings!",
127
- "max_connections": 150,
128
- "timeout": 45,
129
- "debug_mode": True,
130
- "log_level": "INFO"
131
- },
132
- "performance": {
133
- "enable_caching": True,
134
- "cache_ttl": 300,
135
- "max_cache_size": 1000
136
- },
137
- "security": {
138
- "enable_rate_limiting": False,
139
- "max_request_size": "5MB",
140
- "allowed_origins": ["*"]
141
- }
142
- }
143
-
144
- # Write to file
145
- settings_file = "basic_custom_settings.json"
146
- with open(settings_file, 'w', encoding='utf-8') as f:
147
- json.dump(custom_settings, f, indent=2, ensure_ascii=False)
148
-
149
- print(f"āœ… Created custom settings file: {settings_file}")
150
- return settings_file
151
-
152
-
153
- def load_custom_settings_from_file(file_path: str = "basic_custom_settings.json"):
154
- """
155
- Load custom settings from a JSON file.
156
-
157
- Args:
158
- file_path: Path to the custom settings JSON file
159
- """
160
- logger = get_logger("basic_server_custom_settings")
161
-
162
- try:
163
- if os.path.exists(file_path):
164
- with open(file_path, 'r', encoding='utf-8') as f:
165
- custom_settings = json.load(f)
166
-
167
- # Add to framework
168
- add_custom_settings(custom_settings)
169
-
170
- logger.info(f"šŸ“ Loaded custom settings from: {file_path}")
171
- logger.info(f"šŸ“‹ Application: {custom_settings.get('application', {}).get('name', 'Unknown')}")
172
-
173
- return custom_settings
174
- else:
175
- logger.warning(f"āš ļø Custom settings file not found: {file_path}")
176
- return None
177
-
178
- except Exception as e:
179
- logger.error(f"āŒ Failed to load custom settings from {file_path}: {e}")
180
- return None
181
-
182
-
183
- def print_custom_settings_summary():
184
- """
185
- Print a summary of current custom settings.
186
- """
187
- logger = get_logger("basic_server_custom_settings")
188
-
189
- all_settings = get_custom_settings()
190
-
191
- logger.info("šŸ“Š Custom Settings Summary:")
192
-
193
- # Application info
194
- app_name = get_custom_setting_value("application.name", "Unknown")
195
- app_version = get_custom_setting_value("application.version", "0.0.0")
196
- logger.info(f" Application: {app_name} v{app_version}")
197
-
198
- # Features
199
- features = get_custom_setting_value("features", {})
200
- enabled_features = [name for name, enabled in features.items() if enabled]
201
- logger.info(f" Enabled Features: {', '.join(enabled_features) if enabled_features else 'None'}")
202
-
203
- # Demo settings
204
- welcome_msg = get_custom_setting_value("demo_settings.welcome_message", "Hello!")
205
- max_connections = get_custom_setting_value("demo_settings.max_connections", 50)
206
- logger.info(f" Welcome Message: {welcome_msg}")
207
- logger.info(f" Max Connections: {max_connections}")
208
-
209
- # Performance
210
- caching_enabled = get_custom_setting_value("performance.enable_caching", False)
211
- logger.info(f" Caching: {'Enabled' if caching_enabled else 'Disabled'}")
212
-
213
- # Security
214
- rate_limiting = get_custom_setting_value("security.enable_rate_limiting", False)
215
- logger.info(f" Rate Limiting: {'Enabled' if rate_limiting else 'Disabled'}")
216
-
217
- logger.info(f" Total Settings Sections: {len(all_settings)}")
218
-
219
-
220
- if __name__ == "__main__":
221
- # Setup basic custom settings
222
- setup_basic_custom_settings()
223
-
224
- # Demonstrate usage
225
- demo_info = demonstrate_custom_settings_usage()
226
-
227
- # Create custom settings file
228
- settings_file = create_custom_settings_file()
229
-
230
- # Load from file
231
- load_custom_settings_from_file(settings_file)
232
-
233
- # Print summary
234
- print_custom_settings_summary()
235
-
236
- print("\nšŸŽ‰ Custom settings demonstration completed!")
237
- print(f"šŸ“ Custom settings file: {settings_file}")
238
- print("šŸ”§ You can now use these settings in your basic server application.")