mcp-proxy-adapter 2.1.0__py3-none-any.whl → 2.1.1__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 (78) hide show
  1. docs/README.md +172 -0
  2. docs/README_ru.md +172 -0
  3. docs/architecture.md +251 -0
  4. docs/architecture_ru.md +343 -0
  5. docs/command_development.md +250 -0
  6. docs/command_development_ru.md +593 -0
  7. docs/deployment.md +251 -0
  8. docs/deployment_ru.md +1298 -0
  9. docs/examples.md +254 -0
  10. docs/examples_ru.md +401 -0
  11. docs/mcp_proxy_adapter.md +251 -0
  12. docs/mcp_proxy_adapter_ru.md +405 -0
  13. docs/quickstart.md +251 -0
  14. docs/quickstart_ru.md +397 -0
  15. docs/testing.md +255 -0
  16. docs/testing_ru.md +469 -0
  17. docs/validation_ru.md +287 -0
  18. examples/analyze_config.py +141 -0
  19. examples/basic_integration.py +161 -0
  20. examples/docstring_and_schema_example.py +60 -0
  21. examples/extension_example.py +60 -0
  22. examples/help_best_practices.py +67 -0
  23. examples/help_usage.py +64 -0
  24. examples/mcp_proxy_client.py +131 -0
  25. examples/mcp_proxy_config.json +175 -0
  26. examples/openapi_server.py +369 -0
  27. examples/project_structure_example.py +47 -0
  28. examples/testing_example.py +53 -0
  29. mcp_proxy_adapter/__init__.py +17 -0
  30. mcp_proxy_adapter/adapter.py +697 -0
  31. mcp_proxy_adapter/models.py +47 -0
  32. mcp_proxy_adapter/registry.py +439 -0
  33. mcp_proxy_adapter/schema.py +257 -0
  34. {mcp_proxy_adapter-2.1.0.dist-info → mcp_proxy_adapter-2.1.1.dist-info}/METADATA +2 -2
  35. mcp_proxy_adapter-2.1.1.dist-info/RECORD +61 -0
  36. mcp_proxy_adapter-2.1.1.dist-info/top_level.txt +5 -0
  37. scripts/code_analyzer/code_analyzer.py +328 -0
  38. scripts/code_analyzer/register_commands.py +446 -0
  39. scripts/publish.py +85 -0
  40. tests/conftest.py +12 -0
  41. tests/test_adapter.py +529 -0
  42. tests/test_adapter_coverage.py +274 -0
  43. tests/test_basic_dispatcher.py +169 -0
  44. tests/test_command_registry.py +328 -0
  45. tests/test_examples.py +32 -0
  46. tests/test_mcp_proxy_adapter.py +568 -0
  47. tests/test_mcp_proxy_adapter_basic.py +262 -0
  48. tests/test_part1.py +348 -0
  49. tests/test_part2.py +524 -0
  50. tests/test_schema.py +358 -0
  51. tests/test_simple_adapter.py +251 -0
  52. adapters/__init__.py +0 -16
  53. cli/__init__.py +0 -12
  54. cli/__main__.py +0 -79
  55. cli/command_runner.py +0 -233
  56. generators/__init__.py +0 -14
  57. generators/endpoint_generator.py +0 -172
  58. generators/openapi_generator.py +0 -254
  59. generators/rest_api_generator.py +0 -207
  60. mcp_proxy_adapter-2.1.0.dist-info/RECORD +0 -28
  61. mcp_proxy_adapter-2.1.0.dist-info/top_level.txt +0 -7
  62. openapi_schema/__init__.py +0 -38
  63. openapi_schema/command_registry.py +0 -312
  64. openapi_schema/rest_schema.py +0 -510
  65. openapi_schema/rpc_generator.py +0 -307
  66. openapi_schema/rpc_schema.py +0 -416
  67. validators/__init__.py +0 -14
  68. validators/base_validator.py +0 -23
  69. {analyzers → mcp_proxy_adapter/analyzers}/__init__.py +0 -0
  70. {analyzers → mcp_proxy_adapter/analyzers}/docstring_analyzer.py +0 -0
  71. {analyzers → mcp_proxy_adapter/analyzers}/type_analyzer.py +0 -0
  72. {dispatchers → mcp_proxy_adapter/dispatchers}/__init__.py +0 -0
  73. {dispatchers → mcp_proxy_adapter/dispatchers}/base_dispatcher.py +0 -0
  74. {dispatchers → mcp_proxy_adapter/dispatchers}/json_rpc_dispatcher.py +0 -0
  75. {validators → mcp_proxy_adapter/validators}/docstring_validator.py +0 -0
  76. {validators → mcp_proxy_adapter/validators}/metadata_validator.py +0 -0
  77. {mcp_proxy_adapter-2.1.0.dist-info → mcp_proxy_adapter-2.1.1.dist-info}/WHEEL +0 -0
  78. {mcp_proxy_adapter-2.1.0.dist-info → mcp_proxy_adapter-2.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,307 +0,0 @@
1
- """
2
- RPC schema generator from REST schema.
3
- Creates RPC components for all REST endpoints.
4
- """
5
- from typing import Dict, Any, List, Optional
6
-
7
- def generate_rpc_schema(rest_schema: Dict[str, Any]) -> Dict[str, Any]:
8
- """
9
- Generates RPC schema based on REST schema.
10
-
11
- Args:
12
- rest_schema: REST OpenAPI schema
13
-
14
- Returns:
15
- Generated RPC OpenAPI schema
16
- """
17
- # List of available commands (will be filled from REST endpoints)
18
- available_commands = []
19
-
20
- # Create base RPC schema structure
21
- rpc_schema = {
22
- "paths": {
23
- "/cmd": {
24
- "post": {
25
- "summary": "Universal RPC endpoint for executing commands",
26
- "description": "**Main system interaction interface**. The endpoint accepts a structured JSON-RPC 2.0 request with command and parameters, executes the specified operation and returns the result. Only supports working with fixed-dimension vectors of size 384.",
27
- "operationId": "executeCommand",
28
- "requestBody": {
29
- "required": True,
30
- "content": {
31
- "application/json": {
32
- "schema": {
33
- "$ref": "#/components/schemas/CommandRequest"
34
- }
35
- }
36
- }
37
- },
38
- "responses": {
39
- "200": {
40
- "description": "Command execution result (regardless of success or error). API always returns code 200 and uses 'success' field to indicate operation success.",
41
- "content": {
42
- "application/json": {
43
- "schema": {
44
- "$ref": "#/components/schemas/JsonRpcResponse"
45
- }
46
- }
47
- }
48
- }
49
- }
50
- }
51
- }
52
- },
53
- "components": {
54
- "schemas": {},
55
- "examples": {}
56
- }
57
- }
58
-
59
- # Process paths from REST schema and create corresponding commands
60
- command_schemas = {}
61
- command_examples = {}
62
-
63
- for path, path_info in rest_schema["paths"].items():
64
- # Skip path if it starts with /cmd (to avoid RPC endpoint duplication)
65
- if path.startswith("/cmd"):
66
- continue
67
-
68
- # Remove leading slash for command name
69
- command_name = path[1:] if path.startswith('/') else path
70
- # Replace remaining slashes with underscores for command name
71
- command_name = command_name.replace("/", "_")
72
-
73
- # Add command to available list
74
- available_commands.append(command_name)
75
-
76
- # Process each HTTP method (GET, POST etc.)
77
- for method, method_info in path_info.items():
78
- # Get operation description
79
- operation_id = method_info.get("operationId", f"{method}_{command_name}")
80
- summary = method_info.get("summary", f"Operation {command_name}")
81
- description = method_info.get("description", f"Executes operation {command_name}")
82
-
83
- # Create parameter schema for command
84
- param_schema_name = f"{command_name.title()}Params"
85
- param_schema = {
86
- "type": "object",
87
- "title": param_schema_name,
88
- "description": f"Parameters for command {command_name}",
89
- "properties": {},
90
- "required": []
91
- }
92
-
93
- # Process request parameters
94
- if "parameters" in method_info:
95
- for param in method_info["parameters"]:
96
- param_name = param["name"]
97
- param_schema["properties"][param_name] = {
98
- "type": param["schema"].get("type", "string"),
99
- "description": param.get("description", f"Parameter {param_name}")
100
- }
101
-
102
- # Add additional properties from parameter schema
103
- for prop in ["enum", "default", "format", "minimum", "maximum"]:
104
- if prop in param["schema"]:
105
- param_schema["properties"][param_name][prop] = param["schema"][prop]
106
-
107
- # If parameter is required, add it to required list
108
- if param.get("required", False):
109
- param_schema["required"].append(param_name)
110
-
111
- # Process request body parameters
112
- if "requestBody" in method_info and "content" in method_info["requestBody"]:
113
- content = method_info["requestBody"]["content"]
114
- if "application/json" in content and "schema" in content["application/json"]:
115
- body_schema = content["application/json"]["schema"]
116
-
117
- # If request body schema contains reference to another schema
118
- if "$ref" in body_schema:
119
- ref_name = body_schema["$ref"].split("/")[-1]
120
- if ref_name in rest_schema["components"]["schemas"]:
121
- ref_schema = rest_schema["components"]["schemas"][ref_name]
122
-
123
- # Copy properties from request body schema
124
- if "properties" in ref_schema:
125
- for prop_name, prop_info in ref_schema["properties"].items():
126
- # Process references to other schemas in properties
127
- if "$ref" in prop_info:
128
- ref_prop_name = prop_info["$ref"].split("/")[-1]
129
- if ref_prop_name in rest_schema["components"]["schemas"]:
130
- prop_schema = rest_schema["components"]["schemas"][ref_prop_name]
131
- param_schema["properties"][prop_name] = {
132
- "type": prop_schema.get("type", "object"),
133
- "description": prop_schema.get("description", f"Parameter {prop_name}")
134
- }
135
- # If schema contains oneOf or anyOf, process them
136
- for prop in ["oneOf", "anyOf"]:
137
- if prop in prop_schema:
138
- param_schema["properties"][prop_name][prop] = prop_schema[prop]
139
- else:
140
- param_schema["properties"][prop_name] = prop_info
141
-
142
- # Copy required fields list
143
- if "required" in ref_schema:
144
- param_schema["required"].extend(ref_schema["required"])
145
-
146
- # Save parameter schema
147
- command_schemas[param_schema_name] = param_schema
148
-
149
- # Create command usage example
150
- example = {
151
- "summary": summary,
152
- "value": {
153
- "jsonrpc": "2.0",
154
- "command": command_name,
155
- "params": {},
156
- "id": command_name
157
- }
158
- }
159
-
160
- # Fill example with default parameters
161
- for param_name, param_info in param_schema["properties"].items():
162
- if "default" in param_info:
163
- example["value"]["params"][param_name] = param_info["default"]
164
- elif "enum" in param_info and param_info["enum"]:
165
- example["value"]["params"][param_name] = param_info["enum"][0]
166
- elif param_info["type"] == "string":
167
- example["value"]["params"][param_name] = f"example_{param_name}"
168
- elif param_info["type"] == "integer" or param_info["type"] == "number":
169
- example["value"]["params"][param_name] = 1
170
- elif param_info["type"] == "boolean":
171
- example["value"]["params"][param_name] = True
172
- elif param_info["type"] == "array":
173
- example["value"]["params"][param_name] = []
174
- elif param_info["type"] == "object":
175
- example["value"]["params"][param_name] = {}
176
-
177
- # Save example
178
- command_examples[f"{command_name}_example"] = example
179
-
180
- # Special processing for help command
181
- if "help" in available_commands:
182
- # Create examples for help command usage
183
- command_examples["help_all_commands"] = {
184
- "summary": "Get list of all available commands",
185
- "value": {
186
- "jsonrpc": "2.0",
187
- "command": "help",
188
- "params": {},
189
- "id": "help_all"
190
- }
191
- }
192
-
193
- # Examples for specific commands
194
- for command in available_commands:
195
- if command != "help":
196
- command_examples[f"help_{command}_command"] = {
197
- "summary": f"Get help for command {command}",
198
- "value": {
199
- "jsonrpc": "2.0",
200
- "command": "help",
201
- "params": {
202
- "command": command
203
- },
204
- "id": f"help_{command}"
205
- }
206
- }
207
-
208
- # Create base schema for CommandRequest
209
- rpc_schema["components"]["schemas"]["CommandRequest"] = {
210
- "properties": {
211
- "jsonrpc": {
212
- "type": "string",
213
- "description": "JSON-RPC protocol version",
214
- "enum": ["2.0"],
215
- "default": "2.0"
216
- },
217
- "id": {
218
- "type": ["string", "number", "null"],
219
- "description": "Request identifier, used to match requests and responses"
220
- },
221
- "command": {
222
- "type": "string",
223
- "title": "Command",
224
- "description": "Command name to execute",
225
- "enum": available_commands
226
- },
227
- "params": {
228
- "title": "Params",
229
- "description": "Command parameters",
230
- "oneOf": [schema for schema in command_schemas.values()] + [{"type": "null"}]
231
- }
232
- },
233
- "type": "object",
234
- "required": ["command", "jsonrpc"],
235
- "title": "CommandRequest",
236
- "description": "Command execution request via JSON-RPC 2.0"
237
- }
238
-
239
- # Create schema for JSON-RPC response
240
- rpc_schema["components"]["schemas"]["JsonRpcResponse"] = {
241
- "type": "object",
242
- "required": ["jsonrpc", "success"],
243
- "properties": {
244
- "jsonrpc": {
245
- "type": "string",
246
- "description": "JSON-RPC protocol version",
247
- "enum": ["2.0"],
248
- "default": "2.0"
249
- },
250
- "success": {
251
- "type": "boolean",
252
- "description": "Operation success indicator",
253
- "default": False
254
- },
255
- "result": {
256
- "description": "Operation result. Present only on successful execution (success=True). Result format depends on the executed command."
257
- },
258
- "error": {
259
- "description": "Error information. Present only when error occurs (success=false).",
260
- "type": "object",
261
- "required": ["code", "message"],
262
- "properties": {
263
- "code": {
264
- "type": "integer",
265
- "description": "Error code (internal code, not HTTP status)",
266
- "example": 400
267
- },
268
- "message": {
269
- "type": "string",
270
- "description": "Error message description",
271
- "example": "Record does not exist: ID 12345"
272
- }
273
- }
274
- },
275
- "id": {
276
- "type": ["string", "number", "null"],
277
- "description": "Request identifier (if specified in request)"
278
- }
279
- },
280
- "example": {
281
- "jsonrpc": "2.0",
282
- "success": True,
283
- "result": {"id": "550e8400-e29b-41d4-a716-446655440000"},
284
- "id": "request-1"
285
- }
286
- }
287
-
288
- # Add all parameter schemas
289
- rpc_schema["components"]["schemas"].update(command_schemas)
290
-
291
- # Add all examples
292
- rpc_schema["components"]["examples"] = command_examples
293
-
294
- # Add all necessary components from REST schema
295
- for component_type, components in rest_schema["components"].items():
296
- if component_type not in rpc_schema["components"]:
297
- rpc_schema["components"][component_type] = {}
298
-
299
- for component_name, component in components.items():
300
- # Skip components that already exist in RPC schema
301
- if component_name in rpc_schema["components"].get(component_type, {}):
302
- continue
303
-
304
- # Add component to RPC schema
305
- rpc_schema["components"][component_type][component_name] = component
306
-
307
- return rpc_schema