mcp-proxy-adapter 6.3.3__py3-none-any.whl → 6.3.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_proxy_adapter/__init__.py +9 -5
- mcp_proxy_adapter/__main__.py +1 -1
- mcp_proxy_adapter/api/app.py +227 -176
- mcp_proxy_adapter/api/handlers.py +68 -60
- mcp_proxy_adapter/api/middleware/__init__.py +7 -5
- mcp_proxy_adapter/api/middleware/base.py +19 -16
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +44 -34
- mcp_proxy_adapter/api/middleware/error_handling.py +57 -67
- mcp_proxy_adapter/api/middleware/factory.py +50 -52
- mcp_proxy_adapter/api/middleware/logging.py +46 -30
- mcp_proxy_adapter/api/middleware/performance.py +19 -16
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +80 -50
- mcp_proxy_adapter/api/middleware/transport_middleware.py +26 -24
- mcp_proxy_adapter/api/middleware/unified_security.py +70 -51
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +43 -34
- mcp_proxy_adapter/api/schemas.py +69 -43
- mcp_proxy_adapter/api/tool_integration.py +83 -63
- mcp_proxy_adapter/api/tools.py +60 -50
- mcp_proxy_adapter/commands/__init__.py +15 -6
- mcp_proxy_adapter/commands/auth_validation_command.py +107 -110
- mcp_proxy_adapter/commands/base.py +108 -112
- mcp_proxy_adapter/commands/builtin_commands.py +28 -18
- mcp_proxy_adapter/commands/catalog_manager.py +394 -265
- mcp_proxy_adapter/commands/cert_monitor_command.py +222 -204
- mcp_proxy_adapter/commands/certificate_management_command.py +210 -213
- mcp_proxy_adapter/commands/command_registry.py +275 -226
- mcp_proxy_adapter/commands/config_command.py +48 -33
- mcp_proxy_adapter/commands/dependency_container.py +22 -23
- mcp_proxy_adapter/commands/dependency_manager.py +65 -56
- mcp_proxy_adapter/commands/echo_command.py +15 -15
- mcp_proxy_adapter/commands/health_command.py +31 -29
- mcp_proxy_adapter/commands/help_command.py +97 -61
- mcp_proxy_adapter/commands/hooks.py +65 -49
- mcp_proxy_adapter/commands/key_management_command.py +148 -147
- mcp_proxy_adapter/commands/load_command.py +58 -40
- mcp_proxy_adapter/commands/plugins_command.py +80 -54
- mcp_proxy_adapter/commands/protocol_management_command.py +60 -48
- mcp_proxy_adapter/commands/proxy_registration_command.py +107 -115
- mcp_proxy_adapter/commands/reload_command.py +43 -37
- mcp_proxy_adapter/commands/result.py +26 -33
- mcp_proxy_adapter/commands/role_test_command.py +26 -26
- mcp_proxy_adapter/commands/roles_management_command.py +176 -173
- mcp_proxy_adapter/commands/security_command.py +134 -122
- mcp_proxy_adapter/commands/settings_command.py +47 -56
- mcp_proxy_adapter/commands/ssl_setup_command.py +109 -129
- mcp_proxy_adapter/commands/token_management_command.py +129 -158
- mcp_proxy_adapter/commands/transport_management_command.py +41 -36
- mcp_proxy_adapter/commands/unload_command.py +42 -37
- mcp_proxy_adapter/config.py +36 -35
- mcp_proxy_adapter/core/__init__.py +19 -21
- mcp_proxy_adapter/core/app_factory.py +30 -9
- mcp_proxy_adapter/core/app_runner.py +81 -64
- mcp_proxy_adapter/core/auth_validator.py +176 -182
- mcp_proxy_adapter/core/certificate_utils.py +469 -426
- mcp_proxy_adapter/core/client.py +155 -126
- mcp_proxy_adapter/core/client_manager.py +60 -54
- mcp_proxy_adapter/core/client_security.py +108 -88
- mcp_proxy_adapter/core/config_converter.py +176 -143
- mcp_proxy_adapter/core/config_validator.py +12 -4
- mcp_proxy_adapter/core/crl_utils.py +21 -7
- mcp_proxy_adapter/core/errors.py +64 -20
- mcp_proxy_adapter/core/logging.py +34 -29
- mcp_proxy_adapter/core/mtls_asgi.py +29 -25
- mcp_proxy_adapter/core/mtls_asgi_app.py +66 -54
- mcp_proxy_adapter/core/protocol_manager.py +154 -104
- mcp_proxy_adapter/core/proxy_client.py +202 -144
- mcp_proxy_adapter/core/proxy_registration.py +12 -2
- mcp_proxy_adapter/core/role_utils.py +139 -125
- mcp_proxy_adapter/core/security_adapter.py +88 -77
- mcp_proxy_adapter/core/security_factory.py +50 -44
- mcp_proxy_adapter/core/security_integration.py +72 -24
- mcp_proxy_adapter/core/server_adapter.py +68 -64
- mcp_proxy_adapter/core/server_engine.py +71 -53
- mcp_proxy_adapter/core/settings.py +68 -58
- mcp_proxy_adapter/core/ssl_utils.py +69 -56
- mcp_proxy_adapter/core/transport_manager.py +72 -60
- mcp_proxy_adapter/core/unified_config_adapter.py +201 -150
- mcp_proxy_adapter/core/utils.py +4 -2
- mcp_proxy_adapter/custom_openapi.py +107 -99
- mcp_proxy_adapter/examples/basic_framework/main.py +9 -2
- mcp_proxy_adapter/examples/commands/__init__.py +1 -1
- mcp_proxy_adapter/examples/create_certificates_simple.py +182 -71
- mcp_proxy_adapter/examples/debug_request_state.py +38 -19
- mcp_proxy_adapter/examples/debug_role_chain.py +53 -20
- mcp_proxy_adapter/examples/demo_client.py +48 -36
- mcp_proxy_adapter/examples/examples/basic_framework/main.py +9 -2
- mcp_proxy_adapter/examples/examples/full_application/__init__.py +1 -0
- mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +22 -10
- mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +24 -17
- mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +16 -3
- mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +13 -3
- mcp_proxy_adapter/examples/examples/full_application/main.py +27 -2
- mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +48 -14
- mcp_proxy_adapter/examples/full_application/__init__.py +1 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +22 -10
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +24 -17
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +16 -3
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +13 -3
- mcp_proxy_adapter/examples/full_application/main.py +27 -2
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +48 -14
- mcp_proxy_adapter/examples/generate_all_certificates.py +198 -73
- mcp_proxy_adapter/examples/generate_certificates.py +31 -16
- mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +220 -74
- mcp_proxy_adapter/examples/generate_test_configs.py +68 -91
- mcp_proxy_adapter/examples/proxy_registration_example.py +76 -75
- mcp_proxy_adapter/examples/run_example.py +23 -5
- mcp_proxy_adapter/examples/run_full_test_suite.py +109 -71
- mcp_proxy_adapter/examples/run_proxy_server.py +22 -9
- mcp_proxy_adapter/examples/run_security_tests.py +103 -41
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +72 -36
- mcp_proxy_adapter/examples/scripts/config_generator.py +288 -187
- mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +185 -72
- mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +220 -74
- mcp_proxy_adapter/examples/security_test_client.py +196 -127
- mcp_proxy_adapter/examples/setup_test_environment.py +17 -29
- mcp_proxy_adapter/examples/test_config.py +19 -4
- mcp_proxy_adapter/examples/test_config_generator.py +23 -7
- mcp_proxy_adapter/examples/test_examples.py +84 -56
- mcp_proxy_adapter/examples/universal_client.py +119 -62
- mcp_proxy_adapter/openapi.py +108 -115
- mcp_proxy_adapter/utils/config_generator.py +429 -274
- mcp_proxy_adapter/version.py +1 -2
- {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/METADATA +1 -1
- mcp_proxy_adapter-6.3.5.dist-info/RECORD +143 -0
- mcp_proxy_adapter-6.3.3.dist-info/RECORD +0 -143
- {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/licenses/LICENSE +0 -0
- {mcp_proxy_adapter-6.3.3.dist-info → mcp_proxy_adapter-6.3.5.dist-info}/top_level.txt +0 -0
mcp_proxy_adapter/core/utils.py
CHANGED
@@ -34,7 +34,9 @@ def get_timestamp() -> int:
|
|
34
34
|
return int(time.time() * 1000)
|
35
35
|
|
36
36
|
|
37
|
-
def format_datetime(
|
37
|
+
def format_datetime(
|
38
|
+
dt: Optional[datetime] = None, format_str: str = "%Y-%m-%dT%H:%M:%S.%fZ"
|
39
|
+
) -> str:
|
38
40
|
"""
|
39
41
|
Formats date and time as string.
|
40
42
|
|
@@ -113,7 +115,7 @@ def calculate_hash(data: Union[str, bytes], algorithm: str = "sha256") -> str:
|
|
113
115
|
"""
|
114
116
|
if isinstance(data, str):
|
115
117
|
data = data.encode("utf-8")
|
116
|
-
|
118
|
+
|
117
119
|
hash_obj = hashlib.new(algorithm)
|
118
120
|
hash_obj.update(data)
|
119
121
|
return hash_obj.hexdigest()
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"""
|
2
2
|
Custom OpenAPI schema generator for MCP Microservice compatible with MCP-Proxy.
|
3
3
|
"""
|
4
|
+
|
4
5
|
import json
|
5
6
|
from copy import deepcopy
|
6
7
|
from pathlib import Path
|
@@ -17,7 +18,7 @@ from mcp_proxy_adapter.core.logging import logger
|
|
17
18
|
class CustomOpenAPIGenerator:
|
18
19
|
"""
|
19
20
|
Custom OpenAPI schema generator for compatibility with MCP-Proxy.
|
20
|
-
|
21
|
+
|
21
22
|
EN:
|
22
23
|
This generator creates an OpenAPI schema that matches the format expected by MCP-Proxy,
|
23
24
|
enabling dynamic command loading and proper tool representation in AI models.
|
@@ -29,81 +30,87 @@ class CustomOpenAPIGenerator:
|
|
29
30
|
с возможностью динамической подгрузки команд и корректного отображения инструментов для AI-моделей.
|
30
31
|
Поддерживает переопределение title, description и version для кастомизации схемы.
|
31
32
|
"""
|
32
|
-
|
33
|
+
|
33
34
|
def __init__(self):
|
34
35
|
"""Initialize the generator."""
|
35
|
-
self.base_schema_path =
|
36
|
+
self.base_schema_path = (
|
37
|
+
Path(__file__).parent / "schemas" / "openapi_schema.json"
|
38
|
+
)
|
36
39
|
self.base_schema = self._load_base_schema()
|
37
|
-
|
40
|
+
|
38
41
|
def _load_base_schema(self) -> Dict[str, Any]:
|
39
42
|
"""
|
40
43
|
Load the base OpenAPI schema from file.
|
41
|
-
|
44
|
+
|
42
45
|
Returns:
|
43
46
|
Dict containing the base OpenAPI schema.
|
44
47
|
"""
|
45
48
|
with open(self.base_schema_path, "r", encoding="utf-8") as f:
|
46
49
|
return json.load(f)
|
47
|
-
|
50
|
+
|
48
51
|
def _add_commands_to_schema(self, schema: Dict[str, Any]) -> None:
|
49
52
|
"""
|
50
53
|
Add all registered commands to the OpenAPI schema.
|
51
|
-
|
54
|
+
|
52
55
|
Args:
|
53
56
|
schema: The OpenAPI schema to update.
|
54
57
|
"""
|
55
58
|
# Get all commands from the registry
|
56
59
|
commands = registry.get_all_commands()
|
57
|
-
|
60
|
+
|
58
61
|
# Ensure CommandRequest exists in schemas
|
59
62
|
if "CommandRequest" not in schema["components"]["schemas"]:
|
60
63
|
schema["components"]["schemas"]["CommandRequest"] = {
|
61
64
|
"properties": {
|
62
65
|
"command": {"type": "string", "enum": []},
|
63
|
-
"params": {"type": "object", "oneOf": []}
|
66
|
+
"params": {"type": "object", "oneOf": []},
|
64
67
|
}
|
65
68
|
}
|
66
|
-
|
69
|
+
|
67
70
|
# Add command names to the CommandRequest enum
|
68
|
-
schema["components"]["schemas"]["CommandRequest"]["properties"]["command"][
|
69
|
-
|
70
|
-
]
|
71
|
-
|
71
|
+
schema["components"]["schemas"]["CommandRequest"]["properties"]["command"][
|
72
|
+
"enum"
|
73
|
+
] = [cmd for cmd in commands.keys()]
|
74
|
+
|
72
75
|
# Add command parameters to oneOf
|
73
76
|
params_refs = []
|
74
|
-
|
77
|
+
|
75
78
|
for name, cmd_class in commands.items():
|
76
79
|
# Create schema for command parameters
|
77
80
|
param_schema_name = f"{name.capitalize()}Params"
|
78
|
-
schema["components"]["schemas"][param_schema_name] =
|
79
|
-
|
81
|
+
schema["components"]["schemas"][param_schema_name] = (
|
82
|
+
self._create_params_schema(cmd_class)
|
83
|
+
)
|
84
|
+
|
80
85
|
# Add to oneOf
|
81
86
|
params_refs.append({"$ref": f"#/components/schemas/{param_schema_name}"})
|
82
|
-
|
87
|
+
|
83
88
|
# Add null option for commands without parameters
|
84
89
|
params_refs.append({"type": "null"})
|
85
|
-
|
90
|
+
|
86
91
|
# Set oneOf for params
|
87
|
-
schema["components"]["schemas"]["CommandRequest"]["properties"]["params"][
|
88
|
-
|
92
|
+
schema["components"]["schemas"]["CommandRequest"]["properties"]["params"][
|
93
|
+
"oneOf"
|
94
|
+
] = params_refs
|
95
|
+
|
89
96
|
def _create_params_schema(self, cmd_class: Type[Command]) -> Dict[str, Any]:
|
90
97
|
"""
|
91
98
|
Create a schema for command parameters.
|
92
|
-
|
99
|
+
|
93
100
|
Args:
|
94
101
|
cmd_class: The command class.
|
95
|
-
|
102
|
+
|
96
103
|
Returns:
|
97
104
|
Dict containing the parameter schema.
|
98
105
|
"""
|
99
106
|
try:
|
100
107
|
# Get command schema
|
101
108
|
cmd_schema = cmd_class.get_schema()
|
102
|
-
|
109
|
+
|
103
110
|
# Add title and description
|
104
111
|
cmd_schema["title"] = f"Parameters for {cmd_class.name}"
|
105
112
|
cmd_schema["description"] = f"Parameters for the {cmd_class.name} command"
|
106
|
-
|
113
|
+
|
107
114
|
return cmd_schema
|
108
115
|
except Exception as e:
|
109
116
|
# Return default schema if command schema generation fails
|
@@ -113,10 +120,15 @@ class CustomOpenAPIGenerator:
|
|
113
120
|
"title": f"Parameters for {cmd_class.name}",
|
114
121
|
"description": f"Parameters for the {cmd_class.name} command (schema generation failed)",
|
115
122
|
"properties": {},
|
116
|
-
"additionalProperties": True
|
123
|
+
"additionalProperties": True,
|
117
124
|
}
|
118
|
-
|
119
|
-
def generate(
|
125
|
+
|
126
|
+
def generate(
|
127
|
+
self,
|
128
|
+
title: Optional[str] = None,
|
129
|
+
description: Optional[str] = None,
|
130
|
+
version: Optional[str] = None,
|
131
|
+
) -> Dict[str, Any]:
|
120
132
|
"""
|
121
133
|
EN:
|
122
134
|
Generate the complete OpenAPI schema compatible with MCP-Proxy.
|
@@ -125,12 +137,12 @@ class CustomOpenAPIGenerator:
|
|
125
137
|
RU:
|
126
138
|
Генерирует полную схему OpenAPI, совместимую с MCP-Proxy.
|
127
139
|
Позволяет опционально переопределить title, description и version.
|
128
|
-
|
140
|
+
|
129
141
|
Args:
|
130
142
|
title: Custom title for the schema / Кастомный заголовок схемы
|
131
143
|
description: Custom description for the schema / Кастомное описание схемы
|
132
144
|
version: Custom version for the schema / Кастомная версия схемы
|
133
|
-
|
145
|
+
|
134
146
|
Returns:
|
135
147
|
Dict containing the complete OpenAPI schema / Словарь с полной схемой OpenAPI
|
136
148
|
"""
|
@@ -140,26 +152,24 @@ class CustomOpenAPIGenerator:
|
|
140
152
|
# Optionally override info fields
|
141
153
|
if title:
|
142
154
|
schema["info"]["title"] = title
|
143
|
-
|
155
|
+
|
144
156
|
# Get all commands for help information
|
145
157
|
commands = registry.get_all_commands()
|
146
158
|
command_names = list(commands.keys())
|
147
|
-
|
159
|
+
|
148
160
|
# Create help examples
|
149
161
|
help_examples = {
|
150
|
-
"without_params": {
|
151
|
-
"jsonrpc": "2.0",
|
152
|
-
"method": "help",
|
153
|
-
"id": 1
|
154
|
-
},
|
162
|
+
"without_params": {"jsonrpc": "2.0", "method": "help", "id": 1},
|
155
163
|
"with_params": {
|
156
|
-
"jsonrpc": "2.0",
|
157
|
-
"method": "help",
|
158
|
-
"params": {
|
159
|
-
|
160
|
-
|
164
|
+
"jsonrpc": "2.0",
|
165
|
+
"method": "help",
|
166
|
+
"params": {
|
167
|
+
"command": command_names[0] if command_names else "example_command"
|
168
|
+
},
|
169
|
+
"id": 1,
|
170
|
+
},
|
161
171
|
}
|
162
|
-
|
172
|
+
|
163
173
|
# Enhance description with help format and commands list for OpenAPI docs
|
164
174
|
base_description = description or schema["info"]["description"]
|
165
175
|
# В тестах ожидается точное совпадение с исходным описанием
|
@@ -170,37 +180,39 @@ class CustomOpenAPIGenerator:
|
|
170
180
|
# Для обычного использования добавляем информацию о командах и справке
|
171
181
|
commands_str = ", ".join(command_names)
|
172
182
|
help_command_simple = '{"jsonrpc": "2.0", "method": "help", "id": 1}'
|
173
|
-
help_command_with_param =
|
183
|
+
help_command_with_param = (
|
184
|
+
'{"jsonrpc": "2.0", "method": "help", "params": {"command": "'
|
185
|
+
)
|
174
186
|
if command_names:
|
175
187
|
help_command_with_param += command_names[0]
|
176
188
|
else:
|
177
189
|
help_command_with_param += "example_command"
|
178
190
|
help_command_with_param += '"}, "id": 1}'
|
179
|
-
|
191
|
+
|
180
192
|
enhanced_description = (
|
181
|
-
base_description
|
182
|
-
"\n\n## Available commands:\n"
|
183
|
-
|
184
|
-
"\n\n## Getting help\n\n"
|
185
|
-
"Without parameters (list of all commands):\n"
|
186
|
-
"```json\n"
|
187
|
-
|
188
|
-
"\n```\n\n"
|
189
|
-
"With parameters (information about a specific command):\n"
|
190
|
-
"```json\n"
|
191
|
-
|
192
|
-
"\n```\n"
|
193
|
+
base_description
|
194
|
+
+ "\n\n## Available commands:\n"
|
195
|
+
+ commands_str
|
196
|
+
+ "\n\n## Getting help\n\n"
|
197
|
+
+ "Without parameters (list of all commands):\n"
|
198
|
+
+ "```json\n"
|
199
|
+
+ help_command_simple
|
200
|
+
+ "\n```\n\n"
|
201
|
+
+ "With parameters (information about a specific command):\n"
|
202
|
+
+ "```json\n"
|
203
|
+
+ help_command_with_param
|
204
|
+
+ "\n```\n"
|
193
205
|
)
|
194
|
-
|
206
|
+
|
195
207
|
# Set enhanced description for OpenAPI docs
|
196
208
|
schema["info"]["description"] = enhanced_description
|
197
|
-
|
209
|
+
|
198
210
|
# Update tool description visible in MCP-Proxy
|
199
211
|
if "components" not in schema:
|
200
212
|
schema["components"] = {}
|
201
213
|
if "schemas" not in schema["components"]:
|
202
214
|
schema["components"]["schemas"] = {}
|
203
|
-
|
215
|
+
|
204
216
|
# Create ToolDescription if it doesn't exist
|
205
217
|
if "ToolDescription" not in schema["components"]["schemas"]:
|
206
218
|
schema["components"]["schemas"]["ToolDescription"] = {
|
@@ -208,25 +220,19 @@ class CustomOpenAPIGenerator:
|
|
208
220
|
"title": "Tool Description",
|
209
221
|
"description": "Description of the microservice tool",
|
210
222
|
"properties": {
|
211
|
-
"name": {
|
212
|
-
"type": "string",
|
213
|
-
"description": "Name of the tool"
|
214
|
-
},
|
223
|
+
"name": {"type": "string", "description": "Name of the tool"},
|
215
224
|
"description": {
|
216
225
|
"type": "string",
|
217
|
-
"description": "Description of the tool"
|
226
|
+
"description": "Description of the tool",
|
218
227
|
},
|
219
|
-
"version": {
|
220
|
-
"type": "string",
|
221
|
-
"description": "Tool version"
|
222
|
-
}
|
228
|
+
"version": {"type": "string", "description": "Tool version"},
|
223
229
|
},
|
224
|
-
"required": ["name", "description"]
|
230
|
+
"required": ["name", "description"],
|
225
231
|
}
|
226
|
-
|
232
|
+
|
227
233
|
# Update tool description content
|
228
234
|
tool_desc = schema["components"]["schemas"]["ToolDescription"]
|
229
|
-
|
235
|
+
|
230
236
|
# Add help format and commands information to the tool description
|
231
237
|
tool_desc_text = "Tool for executing microservice commands.\n\n"
|
232
238
|
tool_desc_text += "## Available commands:\n"
|
@@ -237,9 +243,9 @@ class CustomOpenAPIGenerator:
|
|
237
243
|
tool_desc_text += " \n"
|
238
244
|
tool_desc_text += "- With parameters (information about a specific command): \n"
|
239
245
|
tool_desc_text += ' {"jsonrpc": "2.0", "method": "help", "params": {"command": "command_name"}, "id": 1}\n'
|
240
|
-
|
246
|
+
|
241
247
|
tool_desc["properties"]["description"]["description"] = tool_desc_text
|
242
|
-
|
248
|
+
|
243
249
|
# Add help examples as a new property
|
244
250
|
tool_desc["properties"]["help_examples"] = {
|
245
251
|
"type": "object",
|
@@ -247,33 +253,33 @@ class CustomOpenAPIGenerator:
|
|
247
253
|
"properties": {
|
248
254
|
"without_params": {
|
249
255
|
"type": "object",
|
250
|
-
"description": "Get a list of all commands"
|
256
|
+
"description": "Get a list of all commands",
|
251
257
|
},
|
252
258
|
"with_params": {
|
253
259
|
"type": "object",
|
254
|
-
"description": "Get information about a specific command"
|
255
|
-
}
|
260
|
+
"description": "Get information about a specific command",
|
261
|
+
},
|
256
262
|
},
|
257
|
-
"example": help_examples
|
263
|
+
"example": help_examples,
|
258
264
|
}
|
259
|
-
|
265
|
+
|
260
266
|
# Add available commands as a new property
|
261
267
|
tool_desc["properties"]["available_commands"] = {
|
262
268
|
"type": "array",
|
263
269
|
"description": "List of available commands",
|
264
|
-
"items": {
|
265
|
-
|
266
|
-
},
|
267
|
-
"example": command_names
|
270
|
+
"items": {"type": "string"},
|
271
|
+
"example": command_names,
|
268
272
|
}
|
269
|
-
|
273
|
+
|
270
274
|
if version:
|
271
275
|
schema["info"]["version"] = version
|
272
276
|
|
273
277
|
# Add commands to schema
|
274
278
|
self._add_commands_to_schema(schema)
|
275
279
|
|
276
|
-
logger.debug(
|
280
|
+
logger.debug(
|
281
|
+
f"Generated OpenAPI schema with {len(registry.get_all_commands())} commands"
|
282
|
+
)
|
277
283
|
|
278
284
|
return schema
|
279
285
|
|
@@ -287,18 +293,18 @@ def custom_openapi(app: FastAPI) -> Dict[str, Any]:
|
|
287
293
|
RU:
|
288
294
|
Создаёт кастомную OpenAPI-схему для FastAPI-приложения.
|
289
295
|
Передаёт параметры title, description и version из приложения в генератор схемы.
|
290
|
-
|
296
|
+
|
291
297
|
Args:
|
292
298
|
app: The FastAPI application / FastAPI-приложение
|
293
|
-
|
299
|
+
|
294
300
|
Returns:
|
295
301
|
Dict containing the custom OpenAPI schema / Словарь с кастомной OpenAPI-схемой
|
296
302
|
"""
|
297
303
|
generator = CustomOpenAPIGenerator()
|
298
304
|
openapi_schema = generator.generate(
|
299
|
-
title=getattr(app,
|
300
|
-
description=getattr(app,
|
301
|
-
version=getattr(app,
|
305
|
+
title=getattr(app, "title", None),
|
306
|
+
description=getattr(app, "description", None),
|
307
|
+
version=getattr(app, "version", None),
|
302
308
|
)
|
303
309
|
|
304
310
|
# Cache the schema
|
@@ -311,10 +317,12 @@ def custom_openapi(app: FastAPI) -> Dict[str, Any]:
|
|
311
317
|
_openapi_generators: Dict[str, Callable] = {}
|
312
318
|
|
313
319
|
|
314
|
-
def register_openapi_generator(
|
320
|
+
def register_openapi_generator(
|
321
|
+
name: str, generator_func: Callable[[FastAPI], Dict[str, Any]]
|
322
|
+
) -> None:
|
315
323
|
"""
|
316
324
|
Register a custom OpenAPI generator.
|
317
|
-
|
325
|
+
|
318
326
|
Args:
|
319
327
|
name: Generator name.
|
320
328
|
generator_func: Function that generates OpenAPI schema.
|
@@ -326,10 +334,10 @@ def register_openapi_generator(name: str, generator_func: Callable[[FastAPI], Di
|
|
326
334
|
def get_openapi_generator(name: str) -> Optional[Callable[[FastAPI], Dict[str, Any]]]:
|
327
335
|
"""
|
328
336
|
Get a custom OpenAPI generator by name.
|
329
|
-
|
337
|
+
|
330
338
|
Args:
|
331
339
|
name: Generator name.
|
332
|
-
|
340
|
+
|
333
341
|
Returns:
|
334
342
|
Generator function or None if not found.
|
335
343
|
"""
|
@@ -339,7 +347,7 @@ def get_openapi_generator(name: str) -> Optional[Callable[[FastAPI], Dict[str, A
|
|
339
347
|
def list_openapi_generators() -> List[str]:
|
340
348
|
"""
|
341
349
|
Get list of registered OpenAPI generators.
|
342
|
-
|
350
|
+
|
343
351
|
Returns:
|
344
352
|
List of generator names.
|
345
353
|
"""
|
@@ -357,10 +365,10 @@ def custom_openapi_with_fallback(app: FastAPI) -> Dict[str, Any]:
|
|
357
365
|
Создаёт кастомную OpenAPI-схему для FastAPI-приложения.
|
358
366
|
Сначала проверяет наличие кастомных генераторов, затем использует встроенный генератор.
|
359
367
|
Передаёт параметры title, description и version из приложения в генератор схемы.
|
360
|
-
|
368
|
+
|
361
369
|
Args:
|
362
370
|
app: The FastAPI application / FastAPI-приложение
|
363
|
-
|
371
|
+
|
364
372
|
Returns:
|
365
373
|
Dict containing the custom OpenAPI schema / Словарь с кастомной OpenAPI-схемой
|
366
374
|
"""
|
@@ -371,7 +379,7 @@ def custom_openapi_with_fallback(app: FastAPI) -> Dict[str, Any]:
|
|
371
379
|
generator_func = _openapi_generators[generator_name]
|
372
380
|
logger.debug(f"Using custom OpenAPI generator: {generator_name}")
|
373
381
|
return generator_func(app)
|
374
|
-
|
382
|
+
|
375
383
|
# Fall back to default generator
|
376
384
|
logger.debug("Using default OpenAPI generator")
|
377
|
-
return custom_openapi(app)
|
385
|
+
return custom_openapi(app)
|
@@ -9,13 +9,18 @@ email: vasilyvz@gmail.com
|
|
9
9
|
import sys
|
10
10
|
import argparse
|
11
11
|
from pathlib import Path
|
12
|
+
|
12
13
|
# Add the framework to the path
|
13
14
|
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
14
15
|
from mcp_proxy_adapter.core.app_factory import create_and_run_server
|
16
|
+
|
17
|
+
|
15
18
|
def main():
|
16
19
|
"""Main entry point for the basic framework example."""
|
17
20
|
parser = argparse.ArgumentParser(description="Basic Framework Example")
|
18
|
-
parser.add_argument(
|
21
|
+
parser.add_argument(
|
22
|
+
"--config", "-c", required=True, help="Path to configuration file"
|
23
|
+
)
|
19
24
|
parser.add_argument("--host", help="Server host")
|
20
25
|
parser.add_argument("--port", type=int, help="Server port")
|
21
26
|
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
|
@@ -38,7 +43,9 @@ def main():
|
|
38
43
|
description="Basic MCP Proxy Adapter with minimal configuration",
|
39
44
|
version="1.0.0",
|
40
45
|
host=config_overrides.get("host", "0.0.0.0"),
|
41
|
-
log_level="debug" if config_overrides.get("debug", False) else "info"
|
46
|
+
log_level="debug" if config_overrides.get("debug", False) else "info",
|
42
47
|
)
|
48
|
+
|
49
|
+
|
43
50
|
if __name__ == "__main__":
|
44
51
|
main()
|