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.
@@ -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
- pass
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 = {"echo": self.echo}
21
- self.commands_info = {"echo": {"description": "Echo input string", "params": {"text": {"type": "string", "description": "Text to echo", "required": True}}}}
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('async', x=10))
70
+ result_async = asyncio.run(registry.execute('async_double', x=10))
60
71
  print(result_async) # 20
61
72
 
62
73
  if __name__ == "__main__":
@@ -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 through the dispatcher.
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
- return self.dispatcher.execute(command, **kwargs)
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
- return self.execute(command, **params)
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
- return self.commands[command](**params)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-proxy-adapter
3
- Version: 2.1.14
3
+ Version: 2.1.15
4
4
  Summary: Adapter for exposing Command Registry commands as tools for AI models via MCP Proxy.
5
5
  Home-page: https://github.com/vasilyvz/mcp-proxy-adapter
6
6
  Author: Vasiliy VZ
@@ -1,28 +1,28 @@
1
- mcp_proxy_adapter/adapter.py,sha256=76dkVeDuqLsJ5AhuftzLlwy2M6yr_PfNbmNfo9dXVhc,28844
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=jgC4TKaPbMbAsoxvGp2ToaOE4drD-VfZug7WJbm4IW4,15853
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=RWjQFNSUtVkeP0qNzp6_jrT6_tub3w_052DrRmvxVk0,4243
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=S5_Xri058jAmOWeit1tedB_GMZQ9RLcNcYabA83ZF6k,2288
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=wFg3Cf2Jgve0J5kFzApvFSII8JOsOGaych64hIC7FqQ,2183
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=sswTo6FZb1F5juHa0FYG3cgvrh3wfgGfJu2bBy5tCm4,1460
21
- mcp_proxy_adapter/examples/testing_example.py,sha256=OxFUhGP9OXiu9eWjSpytpQ5MzoR9uww3M4jYb0_v7dc,2004
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.14.dist-info/licenses/LICENSE,sha256=OkApFEwdgMCt_mbvUI-eIwKMSTe38K3XnU2DT5ub-wI,1072
25
- mcp_proxy_adapter-2.1.14.dist-info/METADATA,sha256=7Pdio5dg10wtV5ClYd4TYAERlEhV13qXLcc9RKqCN2c,8886
26
- mcp_proxy_adapter-2.1.14.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
27
- mcp_proxy_adapter-2.1.14.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
28
- mcp_proxy_adapter-2.1.14.dist-info/RECORD,,
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,,