mcp-proxy-adapter 2.1.14__py3-none-any.whl → 2.1.15__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/adapter.py +2 -2
- mcp_proxy_adapter/dispatchers/base_dispatcher.py +2 -2
- mcp_proxy_adapter/examples/docstring_and_schema_example.py +3 -3
- mcp_proxy_adapter/examples/project_structure_example.py +7 -2
- mcp_proxy_adapter/examples/testing_example.py +14 -3
- mcp_proxy_adapter/registry.py +8 -10
- mcp_proxy_adapter/testing_utils.py +11 -3
- {mcp_proxy_adapter-2.1.14.dist-info → mcp_proxy_adapter-2.1.15.dist-info}/METADATA +1 -1
- {mcp_proxy_adapter-2.1.14.dist-info → mcp_proxy_adapter-2.1.15.dist-info}/RECORD +12 -12
- {mcp_proxy_adapter-2.1.14.dist-info → mcp_proxy_adapter-2.1.15.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-2.1.14.dist-info → mcp_proxy_adapter-2.1.15.dist-info}/licenses/LICENSE +0 -0
- {mcp_proxy_adapter-2.1.14.dist-info → mcp_proxy_adapter-2.1.15.dist-info}/top_level.txt +0 -0
mcp_proxy_adapter/adapter.py
CHANGED
@@ -236,7 +236,7 @@ class MCPProxyAdapter:
|
|
236
236
|
# Execute the command
|
237
237
|
logger.debug(f"Executing command {request.method} with parameters {request.params}")
|
238
238
|
try:
|
239
|
-
result = self.registry.dispatcher.execute(
|
239
|
+
result = await self.registry.dispatcher.execute(
|
240
240
|
request.method,
|
241
241
|
**request.params
|
242
242
|
)
|
@@ -537,7 +537,7 @@ class MCPProxyAdapter:
|
|
537
537
|
|
538
538
|
# Execute the command
|
539
539
|
try:
|
540
|
-
result = self.registry.dispatcher.execute(command, **params)
|
540
|
+
result = await self.registry.dispatcher.execute(command, **params)
|
541
541
|
|
542
542
|
# Return result in MCP Proxy format
|
543
543
|
return {"result": result}
|
@@ -34,7 +34,7 @@ class BaseDispatcher(ABC):
|
|
34
34
|
pass
|
35
35
|
|
36
36
|
@abstractmethod
|
37
|
-
def execute(self, command: str, **kwargs) -> Any:
|
37
|
+
async def execute(self, command: str, **kwargs) -> Any:
|
38
38
|
"""
|
39
39
|
Executes a command with the specified parameters.
|
40
40
|
|
@@ -49,7 +49,7 @@ class BaseDispatcher(ABC):
|
|
49
49
|
CommandNotFoundError: If command is not found
|
50
50
|
CommandExecutionError: On command execution error
|
51
51
|
"""
|
52
|
-
|
52
|
+
raise NotImplementedError("Method must be overridden in subclass")
|
53
53
|
|
54
54
|
@abstractmethod
|
55
55
|
def get_valid_commands(self) -> List[str]:
|
@@ -33,13 +33,13 @@ class MyRegistry:
|
|
33
33
|
return self.commands_info.get(command)
|
34
34
|
def get_commands_info(self):
|
35
35
|
return self.commands_info
|
36
|
-
def execute(self, command, **params):
|
36
|
+
async def execute(self, command, **params):
|
37
37
|
if command == "sum":
|
38
|
-
return self.sum_numbers(**params)
|
38
|
+
return await self.sum_numbers(**params)
|
39
39
|
raise KeyError(f"Unknown command: {command}")
|
40
40
|
def add_generator(self, generator):
|
41
41
|
pass
|
42
|
-
def sum_numbers(self, a: int, b: int) -> int:
|
42
|
+
async def sum_numbers(self, a: int, b: int) -> int:
|
43
43
|
"""
|
44
44
|
Returns the sum of two numbers.
|
45
45
|
|
@@ -10,6 +10,7 @@ Run:
|
|
10
10
|
"""
|
11
11
|
import os
|
12
12
|
import sys
|
13
|
+
import asyncio
|
13
14
|
sys.path.insert(0, os.path.abspath(os.path.dirname(os.path.dirname(__file__))))
|
14
15
|
from fastapi import FastAPI
|
15
16
|
from mcp_proxy_adapter.adapter import MCPProxyAdapter
|
@@ -26,7 +27,7 @@ class MyRegistry:
|
|
26
27
|
return self.commands_info.get(command)
|
27
28
|
def get_commands_info(self):
|
28
29
|
return self.commands_info
|
29
|
-
def execute(self, command, **params):
|
30
|
+
async def execute(self, command, **params):
|
30
31
|
if command == "hello":
|
31
32
|
return {"message": "Hello, world!"}
|
32
33
|
raise KeyError(f"Unknown command: {command}")
|
@@ -44,4 +45,8 @@ adapter.register_endpoints(app)
|
|
44
45
|
|
45
46
|
if __name__ == "__main__":
|
46
47
|
import uvicorn
|
47
|
-
uvicorn.run(app, host="0.0.0.0", port=8000)
|
48
|
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
49
|
+
|
50
|
+
# Call sync handler
|
51
|
+
result_sync = registry.execute('hello')
|
52
|
+
print(result_sync) # {'message': 'Hello, world!'}
|
@@ -17,8 +17,14 @@ from mcp_proxy_adapter.adapter import MCPProxyAdapter
|
|
17
17
|
class MyRegistry:
|
18
18
|
def __init__(self):
|
19
19
|
self.dispatcher = self
|
20
|
-
self.commands = {
|
21
|
-
|
20
|
+
self.commands = {
|
21
|
+
"echo": self.echo,
|
22
|
+
"async_double": self.async_double
|
23
|
+
}
|
24
|
+
self.commands_info = {
|
25
|
+
"echo": {"description": "Echo input string", "params": {"text": {"type": "string", "description": "Text to echo", "required": True}}},
|
26
|
+
"async_double": {"description": "Double the input asynchronously", "params": {"x": {"type": "integer", "description": "Value to double", "required": True}}}
|
27
|
+
}
|
22
28
|
def get_valid_commands(self):
|
23
29
|
return list(self.commands.keys())
|
24
30
|
def get_command_info(self, command):
|
@@ -28,12 +34,17 @@ class MyRegistry:
|
|
28
34
|
def execute(self, command, **params):
|
29
35
|
if command == "echo":
|
30
36
|
return self.echo(**params)
|
37
|
+
if command == "async_double":
|
38
|
+
return self.async_double(**params)
|
31
39
|
raise KeyError(f"Unknown command: {command}")
|
32
40
|
def add_generator(self, generator):
|
33
41
|
pass
|
34
42
|
def echo(self, text: str) -> str:
|
35
43
|
"""Echo input string."""
|
36
44
|
return text
|
45
|
+
async def async_double(self, x: int) -> int:
|
46
|
+
await asyncio.sleep(0.01)
|
47
|
+
return x * 2
|
37
48
|
|
38
49
|
def test_echo():
|
39
50
|
registry = MyRegistry()
|
@@ -56,7 +67,7 @@ result_sync = registry.execute('echo', text='hi')
|
|
56
67
|
print(result_sync) # hi
|
57
68
|
|
58
69
|
# Call async handler
|
59
|
-
result_async = asyncio.run(registry.execute('
|
70
|
+
result_async = asyncio.run(registry.execute('async_double', x=10))
|
60
71
|
print(result_async) # 20
|
61
72
|
|
62
73
|
if __name__ == "__main__":
|
mcp_proxy_adapter/registry.py
CHANGED
@@ -416,18 +416,16 @@ class CommandRegistry:
|
|
416
416
|
|
417
417
|
return stats
|
418
418
|
|
419
|
-
def execute(self, command: str, **kwargs) -> Any:
|
419
|
+
async def execute(self, command: str, **kwargs) -> Any:
|
420
420
|
"""
|
421
|
-
Executes a command
|
422
|
-
|
423
|
-
Args:
|
424
|
-
command: Command name
|
425
|
-
**kwargs: Command parameters
|
426
|
-
|
427
|
-
Returns:
|
428
|
-
Any: Command execution result
|
421
|
+
Executes a command with the specified parameters.
|
429
422
|
"""
|
430
|
-
|
423
|
+
if command not in self._commands_info:
|
424
|
+
raise KeyError(f"Unknown command: {command}")
|
425
|
+
handler = self._commands_info[command]["handler"]
|
426
|
+
if inspect.iscoroutinefunction(handler):
|
427
|
+
return await handler(**kwargs)
|
428
|
+
return handler(**kwargs)
|
431
429
|
|
432
430
|
def get_commands_info(self) -> Dict[str, Dict[str, Any]]:
|
433
431
|
"""
|
@@ -4,6 +4,9 @@ Test utilities for MCP Proxy Adapter: mock dispatcher, registry, and OpenAPI gen
|
|
4
4
|
Can be used in examples and tests.
|
5
5
|
"""
|
6
6
|
|
7
|
+
import asyncio
|
8
|
+
import inspect
|
9
|
+
|
7
10
|
def success_command(value: int = 1) -> dict:
|
8
11
|
return {"result": value * 2}
|
9
12
|
|
@@ -65,13 +68,18 @@ class MockDispatcher:
|
|
65
68
|
def execute_from_params(self, **params):
|
66
69
|
if "query" in params and params["query"] in self.commands:
|
67
70
|
command = params.pop("query")
|
68
|
-
|
71
|
+
result = self.execute(command, **params)
|
72
|
+
return result
|
69
73
|
return {"available_commands": self.get_valid_commands(), "received_params": params}
|
70
74
|
|
71
|
-
def execute(self, command, **params):
|
75
|
+
async def execute(self, command, **params):
|
72
76
|
if command not in self.commands:
|
73
77
|
raise KeyError(f"Unknown command: {command}")
|
74
|
-
|
78
|
+
handler = self.commands[command]
|
79
|
+
if inspect.iscoroutinefunction(handler):
|
80
|
+
return await handler(**params)
|
81
|
+
loop = asyncio.get_running_loop()
|
82
|
+
return await loop.run_in_executor(None, lambda: handler(**params))
|
75
83
|
|
76
84
|
def get_valid_commands(self):
|
77
85
|
return list(self.commands.keys())
|
@@ -1,28 +1,28 @@
|
|
1
|
-
mcp_proxy_adapter/adapter.py,sha256=
|
1
|
+
mcp_proxy_adapter/adapter.py,sha256=x5pT-t4uT12O3GzLurrKBSQ_hwVpjhCRx5oZ5AdZnpY,28856
|
2
2
|
mcp_proxy_adapter/models.py,sha256=8zVWU6ly18pWozOnKQ2gsGpmTgL37-fFE_Fr1SDW-Nk,2530
|
3
|
-
mcp_proxy_adapter/registry.py,sha256=
|
3
|
+
mcp_proxy_adapter/registry.py,sha256=IXzMthYRHvEq37Y99ID49kv1ovqb-RFccKznBKxBRuc,15926
|
4
4
|
mcp_proxy_adapter/schema.py,sha256=HZM0TTQTSi8ha1TEeVevdCyGZOUPoT1soB7Nex0hV50,10947
|
5
|
-
mcp_proxy_adapter/testing_utils.py,sha256=
|
5
|
+
mcp_proxy_adapter/testing_utils.py,sha256=5drf9PFUcmUiShNZXN5x6FSbDzB-2jCAb1RvleUanW0,4510
|
6
6
|
mcp_proxy_adapter/analyzers/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
7
7
|
mcp_proxy_adapter/analyzers/docstring_analyzer.py,sha256=T3FLJEo_uChShfiEKRl8GpVoHvh5HiudZkxnj4KixfA,7541
|
8
8
|
mcp_proxy_adapter/analyzers/type_analyzer.py,sha256=6Wac7osKwF03waFSwQ8ZM0Wqn_zAP2D-I4WMEpR0hQM,5230
|
9
9
|
mcp_proxy_adapter/dispatchers/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
10
|
-
mcp_proxy_adapter/dispatchers/base_dispatcher.py,sha256=
|
10
|
+
mcp_proxy_adapter/dispatchers/base_dispatcher.py,sha256=G9_dMwboNmpvg9OapWKEXI52QsEiIigfjLMs_7tMbNg,2356
|
11
11
|
mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py,sha256=sdRwvI5f-2dtI7U_sv6-pqUvxBMirgUDl_P7la3EV0A,8054
|
12
12
|
mcp_proxy_adapter/examples/analyze_config.py,sha256=vog7TNHDw5ZoYhQLbAvZvEoufmQwH54KJzQBJrSq5w4,4283
|
13
13
|
mcp_proxy_adapter/examples/basic_integration.py,sha256=mtRval4VSUgTb_C2p8U_DPPSEKA08dZYKZk-bOrE4H4,4470
|
14
|
-
mcp_proxy_adapter/examples/docstring_and_schema_example.py,sha256=
|
14
|
+
mcp_proxy_adapter/examples/docstring_and_schema_example.py,sha256=8a6k7_wG1afnjzqCD6W_LBM-N8k3t0w1H_au3-14ds8,2201
|
15
15
|
mcp_proxy_adapter/examples/extension_example.py,sha256=2UnrcHw0yRZuFzyvW6zsJ8_NTmGWU79fnCEG6w8VRDY,2525
|
16
16
|
mcp_proxy_adapter/examples/help_best_practices.py,sha256=Bit9Ywl9vGvM_kuV8DJ6pIDK4mY4mF2Gia9rLc56RpI,2646
|
17
17
|
mcp_proxy_adapter/examples/help_usage.py,sha256=JIUsZofdLFyI7FcwPF-rLxipF1-HaZINzVK1KBh0vxA,2577
|
18
18
|
mcp_proxy_adapter/examples/mcp_proxy_client.py,sha256=z4IzFlGigVTQSb8TpcrQ_a0migsmC58LnNwc8wZmTfw,3811
|
19
19
|
mcp_proxy_adapter/examples/openapi_server.py,sha256=5gRM-EHvMsnNtS_M6l_pNPN5EkSf4X1Lcq4E1Xs5tp0,13387
|
20
|
-
mcp_proxy_adapter/examples/project_structure_example.py,sha256=
|
21
|
-
mcp_proxy_adapter/examples/testing_example.py,sha256=
|
20
|
+
mcp_proxy_adapter/examples/project_structure_example.py,sha256=aWQwQqNn3JOCAB6ngYx_JOUh8uy73B6Q51r6HsPUUmM,1593
|
21
|
+
mcp_proxy_adapter/examples/testing_example.py,sha256=s_ln2U7sMdCey87gmrh9-SjZMF2EW602uGhI1rDsCaM,2461
|
22
22
|
mcp_proxy_adapter/validators/docstring_validator.py,sha256=Onpq2iNJ1qF4ejkJJIlBkLROuSNIVALHVmXIgkCpaFI,2934
|
23
23
|
mcp_proxy_adapter/validators/metadata_validator.py,sha256=uCrn38-VYYn89l6f5CC_GoTAHAweaOW2Z6Esro1rtGw,3155
|
24
|
-
mcp_proxy_adapter-2.1.
|
25
|
-
mcp_proxy_adapter-2.1.
|
26
|
-
mcp_proxy_adapter-2.1.
|
27
|
-
mcp_proxy_adapter-2.1.
|
28
|
-
mcp_proxy_adapter-2.1.
|
24
|
+
mcp_proxy_adapter-2.1.15.dist-info/licenses/LICENSE,sha256=OkApFEwdgMCt_mbvUI-eIwKMSTe38K3XnU2DT5ub-wI,1072
|
25
|
+
mcp_proxy_adapter-2.1.15.dist-info/METADATA,sha256=nUnnfN0k4rxhUdLgJKk6hJd_6S9I5hswuG3baEHL42Q,8886
|
26
|
+
mcp_proxy_adapter-2.1.15.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
27
|
+
mcp_proxy_adapter-2.1.15.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
|
28
|
+
mcp_proxy_adapter-2.1.15.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|