mcp-proxy-adapter 2.1.10__py3-none-any.whl → 2.1.11__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/dispatchers/json_rpc_dispatcher.py +10 -10
- mcp_proxy_adapter/examples/help_usage.py +10 -10
- mcp_proxy_adapter/examples/openapi_server.py +86 -100
- {mcp_proxy_adapter-2.1.10.dist-info → mcp_proxy_adapter-2.1.11.dist-info}/METADATA +1 -1
- {mcp_proxy_adapter-2.1.10.dist-info → mcp_proxy_adapter-2.1.11.dist-info}/RECORD +8 -8
- {mcp_proxy_adapter-2.1.10.dist-info → mcp_proxy_adapter-2.1.11.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-2.1.10.dist-info → mcp_proxy_adapter-2.1.11.dist-info}/licenses/LICENSE +0 -0
- {mcp_proxy_adapter-2.1.10.dist-info → mcp_proxy_adapter-2.1.11.dist-info}/top_level.txt +0 -0
@@ -41,7 +41,7 @@ class JsonRpcDispatcher(BaseDispatcher):
|
|
41
41
|
description="Returns information about available commands",
|
42
42
|
summary="Command help",
|
43
43
|
params={
|
44
|
-
"
|
44
|
+
"cmdname": {
|
45
45
|
"type": "string",
|
46
46
|
"description": "Command name for detailed information",
|
47
47
|
"required": False
|
@@ -160,7 +160,7 @@ class JsonRpcDispatcher(BaseDispatcher):
|
|
160
160
|
|
161
161
|
Args:
|
162
162
|
params: Command parameters
|
163
|
-
|
163
|
+
cmdname: Command name for detailed information
|
164
164
|
|
165
165
|
Returns:
|
166
166
|
Dict[str, Any]: Command help information
|
@@ -168,18 +168,18 @@ class JsonRpcDispatcher(BaseDispatcher):
|
|
168
168
|
if not params:
|
169
169
|
params = {}
|
170
170
|
|
171
|
-
#
|
172
|
-
if "
|
173
|
-
|
174
|
-
if
|
171
|
+
# Only support 'cmdname' parameter
|
172
|
+
if "cmdname" in params and params["cmdname"]:
|
173
|
+
cmdname = params["cmdname"]
|
174
|
+
if cmdname not in self._metadata:
|
175
175
|
return {
|
176
|
-
"error": f"Command '{
|
176
|
+
"error": f"Command '{cmdname}' not found",
|
177
177
|
"available_commands": list(self._metadata.keys())
|
178
178
|
}
|
179
179
|
|
180
180
|
return {
|
181
|
-
"
|
182
|
-
"info": self._metadata[
|
181
|
+
"cmdname": cmdname,
|
182
|
+
"info": self._metadata[cmdname]
|
183
183
|
}
|
184
184
|
|
185
185
|
# Otherwise return brief information about all commands
|
@@ -194,5 +194,5 @@ class JsonRpcDispatcher(BaseDispatcher):
|
|
194
194
|
return {
|
195
195
|
"commands": commands_info,
|
196
196
|
"total": len(commands_info),
|
197
|
-
"note": "
|
197
|
+
"note": "To get info about a specific command, call help with parameter: POST /cmd {\"command\": \"help\", \"params\": {\"cmdname\": \"<command_name>\"}}. Only the 'cmdname' parameter is supported. Calling 'help <command>' (with space) is NOT supported."
|
198
198
|
}
|
@@ -24,29 +24,29 @@ registry = MockRegistry()
|
|
24
24
|
adapter = MCPProxyAdapter(registry)
|
25
25
|
|
26
26
|
# --- Best practice: always check if 'help' is in commands ---
|
27
|
-
def call_help(
|
27
|
+
def call_help(cmdname: str = None) -> Dict[str, Any]:
|
28
28
|
"""Call help command with or without parameter."""
|
29
29
|
dispatcher = registry.dispatcher
|
30
30
|
if "help" in dispatcher.get_valid_commands():
|
31
|
-
if
|
31
|
+
if cmdname:
|
32
32
|
try:
|
33
|
-
return dispatcher.help_command(
|
33
|
+
return dispatcher.help_command(cmdname=cmdname)
|
34
34
|
except Exception as e:
|
35
35
|
print(f"Project help failed: {e}. Fallback to adapter help.")
|
36
|
-
return adapter_help(
|
36
|
+
return adapter_help(cmdname)
|
37
37
|
else:
|
38
38
|
return dispatcher.help_command()
|
39
39
|
else:
|
40
|
-
return adapter_help(
|
40
|
+
return adapter_help(cmdname)
|
41
41
|
|
42
|
-
def adapter_help(
|
42
|
+
def adapter_help(cmdname: str = None) -> Dict[str, Any]:
|
43
43
|
"""Fallback: call adapter's help (simulate)."""
|
44
44
|
dispatcher = registry.dispatcher
|
45
|
-
if not
|
45
|
+
if not cmdname:
|
46
46
|
return {"source": "adapter", "commands": dispatcher.get_valid_commands()}
|
47
|
-
if
|
48
|
-
return {"source": "adapter", "
|
49
|
-
return {"source": "adapter", "error": f"Command '{
|
47
|
+
if cmdname in dispatcher.get_valid_commands():
|
48
|
+
return {"source": "adapter", "cmdname": cmdname, "info": {"description": "Adapter help for command"}}
|
49
|
+
return {"source": "adapter", "error": f"Command '{cmdname}' not found (adapter)", "available_commands": dispatcher.get_valid_commands()}
|
50
50
|
|
51
51
|
if __name__ == "__main__":
|
52
52
|
print("=== Project help (no param) ===")
|
@@ -171,7 +171,7 @@ class MockDispatcher:
|
|
171
171
|
"help": {
|
172
172
|
"description": "Show information about available commands or a specific command.",
|
173
173
|
"params": {
|
174
|
-
"
|
174
|
+
"cmdname": {
|
175
175
|
"type": "string",
|
176
176
|
"description": "Command name for detailed info",
|
177
177
|
"required": False
|
@@ -278,119 +278,105 @@ class MockDispatcher:
|
|
278
278
|
|
279
279
|
def help_command(self, **params):
|
280
280
|
"""Return info about all commands or a specific command."""
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
info = self.commands_info.get(command)
|
281
|
+
cmdname = params.get("cmdname")
|
282
|
+
if cmdname:
|
283
|
+
info = self.commands_info.get(cmdname)
|
285
284
|
if info:
|
286
|
-
return {"
|
285
|
+
return {"cmdname": cmdname, "info": info}
|
287
286
|
else:
|
288
|
-
return {"error": f"Command '{
|
289
|
-
# Если параметр
|
287
|
+
return {"error": f"Command '{cmdname}' not found", "available_commands": list(self.commands_info.keys())}
|
288
|
+
# Если параметр cmdname не указан, возвращаем краткую информацию обо всех
|
290
289
|
return {
|
291
290
|
"commands": {cmd: {"description": info["description"], "params": info["params"]} for cmd, info in self.commands_info.items()},
|
292
291
|
"total": len(self.commands_info),
|
293
|
-
"note": "Use the '
|
292
|
+
"note": "Use the 'cmdname' parameter to get detailed information about a specific command"
|
294
293
|
}
|
295
294
|
|
295
|
+
# --- Создание registry и FastAPI-приложения на верхнем уровне ---
|
296
296
|
class CustomMockRegistry(MockRegistry):
|
297
297
|
"""Custom command registry for example."""
|
298
|
-
|
299
298
|
def __init__(self):
|
300
|
-
"""Initialization with custom dispatcher."""
|
301
299
|
self.dispatcher = MockDispatcher()
|
302
300
|
self.generators = []
|
303
301
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
"""Root endpoint."""
|
341
|
-
return {
|
342
|
-
"message": "OpenAPI Server Example with MCP Proxy Adapter integration",
|
343
|
-
"endpoints": {
|
344
|
-
"items": "/items",
|
345
|
-
"item": "/items/{item_id}",
|
346
|
-
"search": "/items/search",
|
347
|
-
"mcp_proxy": "/cmd"
|
348
|
-
}
|
302
|
+
registry = CustomMockRegistry()
|
303
|
+
app = FastAPI(
|
304
|
+
title="OpenAPI Server Example",
|
305
|
+
description="Example OpenAPI server with MCP Proxy Adapter integration",
|
306
|
+
version="1.0.0"
|
307
|
+
)
|
308
|
+
|
309
|
+
# Configure CORS
|
310
|
+
from fastapi.middleware.cors import CORSMiddleware
|
311
|
+
app.add_middleware(
|
312
|
+
CORSMiddleware,
|
313
|
+
allow_origins=["*"],
|
314
|
+
allow_credentials=True,
|
315
|
+
allow_methods=["*"],
|
316
|
+
allow_headers=["*"],
|
317
|
+
)
|
318
|
+
|
319
|
+
# Create MCP Proxy adapter with explicit endpoint
|
320
|
+
adapter = MCPProxyAdapter(registry, cmd_endpoint="/cmd")
|
321
|
+
# Register adapter endpoints
|
322
|
+
adapter.register_endpoints(app)
|
323
|
+
# Save MCP Proxy configuration to file
|
324
|
+
config_path = os.path.join(os.path.dirname(__file__), "mcp_proxy_config.json")
|
325
|
+
adapter.save_config_to_file(config_path)
|
326
|
+
logger.info(f"MCP Proxy configuration saved to {config_path}")
|
327
|
+
|
328
|
+
# --- REST endpoints ---
|
329
|
+
@app.get("/")
|
330
|
+
def read_root():
|
331
|
+
return {
|
332
|
+
"message": "OpenAPI Server Example with MCP Proxy Adapter integration",
|
333
|
+
"endpoints": {
|
334
|
+
"items": "/items",
|
335
|
+
"item": "/items/{item_id}",
|
336
|
+
"search": "/items/search",
|
337
|
+
"mcp_proxy": "/cmd"
|
349
338
|
}
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
""
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
return registry.dispatcher.search_items(keyword)
|
392
|
-
|
393
|
-
# Start server
|
339
|
+
}
|
340
|
+
|
341
|
+
@app.get("/items", response_model=List[Item])
|
342
|
+
def read_items():
|
343
|
+
return items_db
|
344
|
+
|
345
|
+
@app.get("/items/{item_id}", response_model=Item)
|
346
|
+
def read_item(item_id: int = Path(..., description="Item ID", gt=0)):
|
347
|
+
try:
|
348
|
+
return registry.dispatcher.get_item(item_id)
|
349
|
+
except ValueError as e:
|
350
|
+
return {"error": str(e)}
|
351
|
+
|
352
|
+
@app.post("/items", response_model=Item)
|
353
|
+
def create_new_item(item: Item = Body(..., description="Data of new item")):
|
354
|
+
return registry.dispatcher.create_item(item.model_dump())
|
355
|
+
|
356
|
+
@app.put("/items/{item_id}", response_model=Item)
|
357
|
+
def update_existing_item(
|
358
|
+
item_id: int = Path(..., description="Item ID to update", gt=0),
|
359
|
+
item: Item = Body(..., description="Updated item data")
|
360
|
+
):
|
361
|
+
try:
|
362
|
+
return registry.dispatcher.update_item(item_id, item.model_dump())
|
363
|
+
except ValueError as e:
|
364
|
+
return {"error": str(e)}
|
365
|
+
|
366
|
+
@app.delete("/items/{item_id}")
|
367
|
+
def delete_existing_item(item_id: int = Path(..., description="Item ID to delete", gt=0)):
|
368
|
+
try:
|
369
|
+
return registry.dispatcher.delete_item(item_id)
|
370
|
+
except ValueError as e:
|
371
|
+
return {"error": str(e)}
|
372
|
+
|
373
|
+
@app.get("/items/search", response_model=List[Item])
|
374
|
+
def search_items_by_keyword(keyword: str = Query(..., description="Search keyword")):
|
375
|
+
return registry.dispatcher.search_items(keyword)
|
376
|
+
|
377
|
+
# --- main() только для запуска через python ---
|
378
|
+
def main():
|
379
|
+
import uvicorn
|
394
380
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
395
381
|
|
396
382
|
if __name__ == "__main__":
|
@@ -9,21 +9,21 @@ mcp_proxy_adapter/analyzers/docstring_analyzer.py,sha256=T3FLJEo_uChShfiEKRl8GpV
|
|
9
9
|
mcp_proxy_adapter/analyzers/type_analyzer.py,sha256=6Wac7osKwF03waFSwQ8ZM0Wqn_zAP2D-I4WMEpR0hQM,5230
|
10
10
|
mcp_proxy_adapter/dispatchers/__init__.py,sha256=FWgimgInGphIjCEnvA3-ZExiapUzYAVis2H9C5IWivU,365
|
11
11
|
mcp_proxy_adapter/dispatchers/base_dispatcher.py,sha256=S5_Xri058jAmOWeit1tedB_GMZQ9RLcNcYabA83ZF6k,2288
|
12
|
-
mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py,sha256=
|
12
|
+
mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py,sha256=S98qSj0p3glfiPcRirqCZaoiD9PrVVM3t7Lrgd6S8kM,6461
|
13
13
|
mcp_proxy_adapter/examples/analyze_config.py,sha256=vog7TNHDw5ZoYhQLbAvZvEoufmQwH54KJzQBJrSq5w4,4283
|
14
14
|
mcp_proxy_adapter/examples/basic_integration.py,sha256=w_oA777YiQt36gzI113KPQ6k45caXbMCqW9hD8sy8zo,4657
|
15
15
|
mcp_proxy_adapter/examples/docstring_and_schema_example.py,sha256=c96L4KF_7yWzffmvd4hyeQuXSdYyYkv7Uvuy0QxgMcQ,1929
|
16
16
|
mcp_proxy_adapter/examples/extension_example.py,sha256=vnatnFdNTapMpPcQ79Ugitk92ZiUfpLTs7Dvsodf1og,2277
|
17
17
|
mcp_proxy_adapter/examples/help_best_practices.py,sha256=Bit9Ywl9vGvM_kuV8DJ6pIDK4mY4mF2Gia9rLc56RpI,2646
|
18
|
-
mcp_proxy_adapter/examples/help_usage.py,sha256=
|
18
|
+
mcp_proxy_adapter/examples/help_usage.py,sha256=9-65TyECtQYqPJLG3tlOWctI1zoCh6dEewh_i8mCdus,2577
|
19
19
|
mcp_proxy_adapter/examples/mcp_proxy_client.py,sha256=z4IzFlGigVTQSb8TpcrQ_a0migsmC58LnNwc8wZmTfw,3811
|
20
|
-
mcp_proxy_adapter/examples/openapi_server.py,sha256=
|
20
|
+
mcp_proxy_adapter/examples/openapi_server.py,sha256=KjUkXnGMnCxiRd71b1NFoHf40y9REXFqnmaxAgK4FB8,13229
|
21
21
|
mcp_proxy_adapter/examples/project_structure_example.py,sha256=sswTo6FZb1F5juHa0FYG3cgvrh3wfgGfJu2bBy5tCm4,1460
|
22
22
|
mcp_proxy_adapter/examples/testing_example.py,sha256=AB13c4C1bjs1145O-yriwyreeVXtMOlQLzs2BCGmprk,1719
|
23
23
|
mcp_proxy_adapter/validators/docstring_validator.py,sha256=Onpq2iNJ1qF4ejkJJIlBkLROuSNIVALHVmXIgkCpaFI,2934
|
24
24
|
mcp_proxy_adapter/validators/metadata_validator.py,sha256=uCrn38-VYYn89l6f5CC_GoTAHAweaOW2Z6Esro1rtGw,3155
|
25
|
-
mcp_proxy_adapter-2.1.
|
26
|
-
mcp_proxy_adapter-2.1.
|
27
|
-
mcp_proxy_adapter-2.1.
|
28
|
-
mcp_proxy_adapter-2.1.
|
29
|
-
mcp_proxy_adapter-2.1.
|
25
|
+
mcp_proxy_adapter-2.1.11.dist-info/licenses/LICENSE,sha256=OkApFEwdgMCt_mbvUI-eIwKMSTe38K3XnU2DT5ub-wI,1072
|
26
|
+
mcp_proxy_adapter-2.1.11.dist-info/METADATA,sha256=2Z-WGz0AwAtHoUkUDhvQ1B_3enFmOj7epWGpm4C7UZo,12579
|
27
|
+
mcp_proxy_adapter-2.1.11.dist-info/WHEEL,sha256=GHB6lJx2juba1wDgXDNlMTyM13ckjBMKf-OnwgKOCtA,91
|
28
|
+
mcp_proxy_adapter-2.1.11.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
|
29
|
+
mcp_proxy_adapter-2.1.11.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|