mcp-proxy-adapter 2.1.16__py3-none-any.whl → 3.0.0__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 (84) hide show
  1. examples/__init__.py +19 -0
  2. examples/anti_patterns/README.md +51 -0
  3. examples/anti_patterns/__init__.py +9 -0
  4. examples/anti_patterns/bad_design/README.md +72 -0
  5. examples/anti_patterns/bad_design/global_state.py +170 -0
  6. examples/anti_patterns/bad_design/monolithic_command.py +272 -0
  7. examples/basic_example/README.md +131 -0
  8. examples/basic_example/__init__.py +8 -0
  9. examples/basic_example/commands/__init__.py +5 -0
  10. examples/basic_example/commands/echo_command.py +95 -0
  11. examples/basic_example/commands/math_command.py +151 -0
  12. examples/basic_example/commands/time_command.py +152 -0
  13. examples/basic_example/config.json +21 -0
  14. examples/basic_example/config.yaml +20 -0
  15. examples/basic_example/docs/EN/README.md +136 -0
  16. examples/basic_example/docs/RU/README.md +136 -0
  17. examples/basic_example/main.py +50 -0
  18. examples/basic_example/server.py +45 -0
  19. examples/basic_example/tests/conftest.py +243 -0
  20. examples/commands/echo_command.py +52 -0
  21. examples/commands/echo_result.py +65 -0
  22. examples/commands/get_date_command.py +98 -0
  23. examples/commands/new_uuid4_command.py +91 -0
  24. examples/complete_example/Dockerfile +24 -0
  25. examples/complete_example/README.md +92 -0
  26. examples/complete_example/__init__.py +8 -0
  27. examples/complete_example/commands/__init__.py +5 -0
  28. examples/complete_example/commands/system_command.py +327 -0
  29. examples/complete_example/config.json +41 -0
  30. examples/complete_example/configs/config.dev.yaml +40 -0
  31. examples/complete_example/configs/config.docker.yaml +40 -0
  32. examples/complete_example/docker-compose.yml +35 -0
  33. examples/complete_example/main.py +67 -0
  34. examples/complete_example/requirements.txt +20 -0
  35. examples/complete_example/server.py +85 -0
  36. examples/minimal_example/README.md +51 -0
  37. examples/minimal_example/__init__.py +8 -0
  38. examples/minimal_example/config.json +21 -0
  39. examples/minimal_example/config.yaml +26 -0
  40. examples/minimal_example/main.py +67 -0
  41. examples/minimal_example/simple_server.py +124 -0
  42. examples/minimal_example/tests/conftest.py +171 -0
  43. examples/minimal_example/tests/test_hello_command.py +111 -0
  44. examples/minimal_example/tests/test_integration.py +183 -0
  45. examples/server.py +69 -0
  46. examples/simple_server.py +137 -0
  47. examples/test_server.py +126 -0
  48. mcp_proxy_adapter/__init__.py +33 -1
  49. mcp_proxy_adapter/config.py +186 -0
  50. mcp_proxy_adapter/custom_openapi.py +125 -0
  51. mcp_proxy_adapter/framework.py +109 -0
  52. mcp_proxy_adapter/openapi.py +403 -0
  53. mcp_proxy_adapter/version.py +3 -0
  54. mcp_proxy_adapter-3.0.0.dist-info/METADATA +200 -0
  55. mcp_proxy_adapter-3.0.0.dist-info/RECORD +58 -0
  56. {mcp_proxy_adapter-2.1.16.dist-info → mcp_proxy_adapter-3.0.0.dist-info}/top_level.txt +1 -0
  57. mcp_proxy_adapter/adapter.py +0 -697
  58. mcp_proxy_adapter/analyzers/__init__.py +0 -1
  59. mcp_proxy_adapter/analyzers/docstring_analyzer.py +0 -199
  60. mcp_proxy_adapter/analyzers/type_analyzer.py +0 -151
  61. mcp_proxy_adapter/dispatchers/__init__.py +0 -1
  62. mcp_proxy_adapter/dispatchers/base_dispatcher.py +0 -85
  63. mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py +0 -235
  64. mcp_proxy_adapter/examples/analyze_config.py +0 -141
  65. mcp_proxy_adapter/examples/basic_integration.py +0 -155
  66. mcp_proxy_adapter/examples/docstring_and_schema_example.py +0 -69
  67. mcp_proxy_adapter/examples/extension_example.py +0 -72
  68. mcp_proxy_adapter/examples/help_best_practices.py +0 -67
  69. mcp_proxy_adapter/examples/help_usage.py +0 -64
  70. mcp_proxy_adapter/examples/mcp_proxy_client.py +0 -131
  71. mcp_proxy_adapter/examples/openapi_server.py +0 -383
  72. mcp_proxy_adapter/examples/project_structure_example.py +0 -47
  73. mcp_proxy_adapter/examples/testing_example.py +0 -64
  74. mcp_proxy_adapter/models.py +0 -47
  75. mcp_proxy_adapter/registry.py +0 -439
  76. mcp_proxy_adapter/schema.py +0 -257
  77. mcp_proxy_adapter/testing_utils.py +0 -112
  78. mcp_proxy_adapter/validators/__init__.py +0 -1
  79. mcp_proxy_adapter/validators/docstring_validator.py +0 -75
  80. mcp_proxy_adapter/validators/metadata_validator.py +0 -76
  81. mcp_proxy_adapter-2.1.16.dist-info/METADATA +0 -341
  82. mcp_proxy_adapter-2.1.16.dist-info/RECORD +0 -30
  83. {mcp_proxy_adapter-2.1.16.dist-info → mcp_proxy_adapter-3.0.0.dist-info}/WHEEL +0 -0
  84. {mcp_proxy_adapter-2.1.16.dist-info → mcp_proxy_adapter-3.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,136 @@
1
+ # Basic MCP Microservice Example
2
+
3
+ This example demonstrates the basic functionality of MCP Microservice with multiple commands
4
+ organized in separate files.
5
+
6
+ ## Structure
7
+
8
+ ```
9
+ basic_example/
10
+ ├── commands/ # Commands directory
11
+ │ ├── __init__.py # Package initialization
12
+ │ ├── echo_command.py # Echo command
13
+ │ ├── math_command.py # Math command
14
+ │ └── time_command.py # Time command
15
+ ├── config.yaml # Configuration file
16
+ ├── docs/ # Documentation
17
+ │ ├── EN/ # English documentation
18
+ │ │ └── README.md # This file
19
+ │ └── RU/ # Russian documentation
20
+ │ └── README.md # Russian version of this file
21
+ ├── logs/ # Logs directory
22
+ └── server.py # Server startup file
23
+ ```
24
+
25
+ ## Running the Example
26
+
27
+ ```bash
28
+ # Navigate to the project directory
29
+ cd examples/basic_example
30
+
31
+ # Create logs directory if it doesn't exist
32
+ mkdir -p logs
33
+
34
+ # Run the server
35
+ python server.py
36
+ ```
37
+
38
+ After starting, the server will be available at [http://localhost:8000](http://localhost:8000).
39
+
40
+ ## Available Commands
41
+
42
+ ### 1. `echo` - Echo Command
43
+
44
+ Returns the provided message.
45
+
46
+ **Parameters:**
47
+ - `message` (string) - Message to echo back
48
+
49
+ **Example request:**
50
+ ```json
51
+ {
52
+ "jsonrpc": "2.0",
53
+ "method": "echo",
54
+ "params": {
55
+ "message": "Hello, World!"
56
+ },
57
+ "id": 1
58
+ }
59
+ ```
60
+
61
+ ### 2. `math` - Math Command
62
+
63
+ Performs a math operation on two numbers.
64
+
65
+ **Parameters:**
66
+ - `a` (number) - First number
67
+ - `b` (number) - Second number
68
+ - `operation` (string) - Operation (add, subtract, multiply, divide)
69
+
70
+ **Example request:**
71
+ ```json
72
+ {
73
+ "jsonrpc": "2.0",
74
+ "method": "math",
75
+ "params": {
76
+ "a": 10,
77
+ "b": 5,
78
+ "operation": "add"
79
+ },
80
+ "id": 1
81
+ }
82
+ ```
83
+
84
+ ### 3. `time` - Time Command
85
+
86
+ Returns the current time and date.
87
+
88
+ **Parameters:**
89
+ - `format` (string, optional) - Time format (default: "%Y-%m-%d %H:%M:%S")
90
+ - `timezone` (string, optional) - Timezone (default: "UTC")
91
+
92
+ **Example request:**
93
+ ```json
94
+ {
95
+ "jsonrpc": "2.0",
96
+ "method": "time",
97
+ "params": {
98
+ "format": "%d.%m.%Y %H:%M:%S",
99
+ "timezone": "Europe/London"
100
+ },
101
+ "id": 1
102
+ }
103
+ ```
104
+
105
+ ## Testing the API
106
+
107
+ ### Via Web Interface
108
+
109
+ Open [http://localhost:8000/docs](http://localhost:8000/docs) in your browser to access the Swagger UI interactive documentation.
110
+
111
+ ### Via Command Line
112
+
113
+ ```bash
114
+ # Call echo command via JSON-RPC
115
+ curl -X POST "http://localhost:8000/api/jsonrpc" \
116
+ -H "Content-Type: application/json" \
117
+ -d '{"jsonrpc": "2.0", "method": "echo", "params": {"message": "Hello!"}, "id": 1}'
118
+
119
+ # Call math command via simplified endpoint
120
+ curl -X POST "http://localhost:8000/cmd" \
121
+ -H "Content-Type: application/json" \
122
+ -d '{"command": "math", "params": {"a": 10, "b": 5, "operation": "add"}}'
123
+
124
+ # Call time command via endpoint /api/command/{command_name}
125
+ curl -X POST "http://localhost:8000/api/command/time" \
126
+ -H "Content-Type: application/json" \
127
+ -d '{"format": "%d.%m.%Y %H:%M:%S", "timezone": "UTC"}'
128
+ ```
129
+
130
+ ## Key Features Demonstrated
131
+
132
+ 1. Command organization in separate files
133
+ 2. Automatic command discovery and registration
134
+ 3. Different command types and parameter handling
135
+ 4. Error handling
136
+ 5. Different ways to call commands (JSON-RPC, /cmd, /api/command/{command_name})
@@ -0,0 +1,136 @@
1
+ # Базовый пример MCP Microservice
2
+
3
+ Этот пример демонстрирует базовую функциональность MCP Microservice с несколькими командами,
4
+ организованными в отдельные файлы.
5
+
6
+ ## Структура
7
+
8
+ ```
9
+ basic_example/
10
+ ├── commands/ # Директория с командами
11
+ │ ├── __init__.py # Инициализация пакета
12
+ │ ├── echo_command.py # Команда эхо
13
+ │ ├── math_command.py # Математическая команда
14
+ │ └── time_command.py # Команда времени
15
+ ├── config.yaml # Файл конфигурации
16
+ ├── docs/ # Документация
17
+ │ ├── EN/ # Английская документация
18
+ │ │ └── README.md # Английская версия данного файла
19
+ │ └── RU/ # Русская документация
20
+ │ └── README.md # Этот файл
21
+ ├── logs/ # Директория для логов
22
+ └── server.py # Файл запуска сервера
23
+ ```
24
+
25
+ ## Запуск примера
26
+
27
+ ```bash
28
+ # Перейти в директорию проекта
29
+ cd examples/basic_example
30
+
31
+ # Создать директорию для логов, если она не существует
32
+ mkdir -p logs
33
+
34
+ # Запустить сервер
35
+ python server.py
36
+ ```
37
+
38
+ После запуска сервер будет доступен по адресу [http://localhost:8000](http://localhost:8000).
39
+
40
+ ## Доступные команды
41
+
42
+ ### 1. `echo` - Эхо-команда
43
+
44
+ Возвращает переданное сообщение.
45
+
46
+ **Параметры:**
47
+ - `message` (string) - Сообщение для эхо
48
+
49
+ **Пример запроса:**
50
+ ```json
51
+ {
52
+ "jsonrpc": "2.0",
53
+ "method": "echo",
54
+ "params": {
55
+ "message": "Hello, World!"
56
+ },
57
+ "id": 1
58
+ }
59
+ ```
60
+
61
+ ### 2. `math` - Математическая команда
62
+
63
+ Выполняет математическую операцию над двумя числами.
64
+
65
+ **Параметры:**
66
+ - `a` (number) - Первое число
67
+ - `b` (number) - Второе число
68
+ - `operation` (string) - Операция (add, subtract, multiply, divide)
69
+
70
+ **Пример запроса:**
71
+ ```json
72
+ {
73
+ "jsonrpc": "2.0",
74
+ "method": "math",
75
+ "params": {
76
+ "a": 10,
77
+ "b": 5,
78
+ "operation": "add"
79
+ },
80
+ "id": 1
81
+ }
82
+ ```
83
+
84
+ ### 3. `time` - Команда времени
85
+
86
+ Возвращает текущее время и дату.
87
+
88
+ **Параметры:**
89
+ - `format` (string, опционально) - Формат времени (по умолчанию: "%Y-%m-%d %H:%M:%S")
90
+ - `timezone` (string, опционально) - Часовой пояс (по умолчанию: "UTC")
91
+
92
+ **Пример запроса:**
93
+ ```json
94
+ {
95
+ "jsonrpc": "2.0",
96
+ "method": "time",
97
+ "params": {
98
+ "format": "%d.%m.%Y %H:%M:%S",
99
+ "timezone": "Europe/Moscow"
100
+ },
101
+ "id": 1
102
+ }
103
+ ```
104
+
105
+ ## Тестирование API
106
+
107
+ ### Через веб-интерфейс
108
+
109
+ Откройте в браузере [http://localhost:8000/docs](http://localhost:8000/docs) для доступа к интерактивной документации Swagger UI.
110
+
111
+ ### Через командную строку
112
+
113
+ ```bash
114
+ # Вызов команды echo через JSON-RPC
115
+ curl -X POST "http://localhost:8000/api/jsonrpc" \
116
+ -H "Content-Type: application/json" \
117
+ -d '{"jsonrpc": "2.0", "method": "echo", "params": {"message": "Hello!"}, "id": 1}'
118
+
119
+ # Вызов команды math через упрощенный эндпоинт
120
+ curl -X POST "http://localhost:8000/cmd" \
121
+ -H "Content-Type: application/json" \
122
+ -d '{"command": "math", "params": {"a": 10, "b": 5, "operation": "add"}}'
123
+
124
+ # Вызов команды time через endpoint /api/command/{command_name}
125
+ curl -X POST "http://localhost:8000/api/command/time" \
126
+ -H "Content-Type: application/json" \
127
+ -d '{"format": "%d.%m.%Y %H:%M:%S", "timezone": "UTC"}'
128
+ ```
129
+
130
+ ## Ключевые особенности, демонстрируемые примером
131
+
132
+ 1. Организация команд в отдельные файлы
133
+ 2. Автоматическое обнаружение и регистрация команд
134
+ 3. Различные типы команд и параметров
135
+ 4. Обработка ошибок
136
+ 5. Различные способы вызова команд (JSON-RPC, /cmd, /api/command/{command_name})
@@ -0,0 +1,50 @@
1
+ """
2
+ Пример запуска сервера mcp-proxy-adapter с базовыми командами.
3
+ """
4
+
5
+ import os
6
+ import sys
7
+ import uvicorn
8
+ import logging
9
+
10
+ from mcp_proxy_adapter.api.app import create_app
11
+ from mcp_proxy_adapter.config import config
12
+ from mcp_proxy_adapter.core.logging import setup_logging
13
+
14
+ # Импортируем команды из примера
15
+ from commands.echo_command import EchoCommand
16
+ from commands.math_command import MathCommand
17
+
18
+ def main():
19
+ """
20
+ Основная функция запуска сервера.
21
+ """
22
+ try:
23
+ # Настраиваем логирование
24
+ log_level = config.get("logging.level", "INFO")
25
+ setup_logging(log_level)
26
+
27
+ # Получаем настройки сервера
28
+ host = config.get("server.host", "0.0.0.0")
29
+ port = int(config.get("server.port", 8000))
30
+
31
+ # Регистрируем команды
32
+ app = create_app()
33
+
34
+ # Запускаем сервер
35
+ print(f"Запуск сервера на http://{host}:{port}")
36
+ print(f"Документация доступна по адресу: http://{host}:{port}/docs")
37
+
38
+ uvicorn.run(
39
+ app,
40
+ host=host,
41
+ port=port,
42
+ reload=True if os.environ.get("DEBUG") else False,
43
+ log_level=log_level.lower()
44
+ )
45
+ except Exception as e:
46
+ print(f"Ошибка при запуске приложения: {e}")
47
+ sys.exit(1)
48
+
49
+ if __name__ == "__main__":
50
+ main()
@@ -0,0 +1,45 @@
1
+ """
2
+ Basic MCP Microservice example.
3
+
4
+ This example demonstrates a microservice with multiple commands
5
+ organized in separate files.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ from typing import Dict, Any
11
+
12
+ import mcp_proxy_adapter as mcp
13
+ from mcp_proxy_adapter import MicroService
14
+
15
+ # Add commands directory to path for local imports
16
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
17
+
18
+
19
+ def main():
20
+ """Run microservice with command discovery."""
21
+ # Get absolute paths
22
+ current_dir = os.path.dirname(os.path.abspath(__file__))
23
+ config_path = os.path.join(current_dir, "config.yaml")
24
+
25
+ # Create log directory if it doesn't exist
26
+ os.makedirs(os.path.join(current_dir, "logs"), exist_ok=True)
27
+
28
+ # Create microservice
29
+ service = MicroService(
30
+ title="Basic MCP Microservice Example",
31
+ description="Example microservice with multiple commands",
32
+ version="1.0.0",
33
+ config_path=config_path
34
+ )
35
+
36
+ # Discover and register commands from the commands directory
37
+ package_path = "commands" # Relative import path
38
+ service.discover_commands(package_path)
39
+
40
+ # Run server
41
+ service.run(reload=True)
42
+
43
+
44
+ if __name__ == "__main__":
45
+ main()
@@ -0,0 +1,243 @@
1
+ """
2
+ Pytest configuration and fixtures for basic example tests.
3
+
4
+ This module provides fixtures for testing the basic microservice example,
5
+ including running an actual server instance for integration tests.
6
+ All commands in the microservice are implemented as asynchronous functions.
7
+ """
8
+
9
+ import os
10
+ import sys
11
+ import time
12
+ import socket
13
+ import asyncio
14
+ import threading
15
+ import multiprocessing
16
+ from typing import Callable, Dict, Any, List
17
+
18
+ import pytest
19
+ import requests
20
+
21
+ # Add parent directory to path for imports
22
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
23
+
24
+ # Import the server module from the parent directory
25
+ import server as server_module
26
+ from commands.echo_command import EchoCommand
27
+ from commands.math_command import MathCommand
28
+ from commands.time_command import TimeCommand
29
+
30
+
31
+ def find_free_port() -> int:
32
+ """
33
+ Find a free port on localhost.
34
+
35
+ Returns:
36
+ Free port number
37
+ """
38
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
39
+ sock.bind(('localhost', 0))
40
+ return sock.getsockname()[1]
41
+
42
+
43
+ class ServerProcess:
44
+ """Helper class to manage server process."""
45
+
46
+ def __init__(self, port: int):
47
+ """
48
+ Initialize server process with a specified port.
49
+
50
+ Args:
51
+ port: Port number to use
52
+ """
53
+ self.port = port
54
+ self.process = None
55
+
56
+ def start(self) -> None:
57
+ """Start the server in a separate process."""
58
+ def run_server():
59
+ # Mock the configuration to use the test port
60
+ os.environ["TEST_SERVER_PORT"] = str(self.port)
61
+ server_module.main()
62
+
63
+ self.process = multiprocessing.Process(target=run_server)
64
+ self.process.daemon = True
65
+ self.process.start()
66
+
67
+ # Wait for server to start
68
+ self._wait_for_server()
69
+
70
+ def stop(self) -> None:
71
+ """Stop the server process."""
72
+ if self.process and self.process.is_alive():
73
+ self.process.terminate()
74
+ self.process.join(timeout=2)
75
+
76
+ def _wait_for_server(self, max_attempts: int = 10) -> None:
77
+ """
78
+ Wait for the server to become available.
79
+
80
+ Args:
81
+ max_attempts: Maximum number of connection attempts
82
+ """
83
+ for i in range(max_attempts):
84
+ try:
85
+ response = requests.get(f"http://localhost:{self.port}/health")
86
+ if response.status_code == 200:
87
+ return
88
+ except requests.ConnectionError:
89
+ pass
90
+
91
+ time.sleep(0.5)
92
+
93
+ raise TimeoutError(f"Server did not start within {max_attempts * 0.5} seconds")
94
+
95
+
96
+ @pytest.fixture
97
+ def server_port() -> int:
98
+ """
99
+ Fixture that provides a free port for the test server.
100
+
101
+ Returns:
102
+ Port number
103
+ """
104
+ return find_free_port()
105
+
106
+
107
+ @pytest.fixture
108
+ def server(server_port: int) -> ServerProcess:
109
+ """
110
+ Fixture that provides a running server instance.
111
+
112
+ Args:
113
+ server_port: Port to run the server on
114
+
115
+ Returns:
116
+ Server process object
117
+ """
118
+ server_process = ServerProcess(server_port)
119
+ server_process.start()
120
+
121
+ yield server_process
122
+
123
+ server_process.stop()
124
+
125
+
126
+ @pytest.fixture
127
+ def api_url(server_port: int) -> str:
128
+ """
129
+ Fixture that provides the base API URL.
130
+
131
+ Args:
132
+ server_port: Server port
133
+
134
+ Returns:
135
+ Base API URL
136
+ """
137
+ return f"http://localhost:{server_port}"
138
+
139
+
140
+ @pytest.fixture
141
+ def jsonrpc_client(api_url: str) -> Callable:
142
+ """
143
+ Fixture that provides a JSON-RPC client function.
144
+
145
+ Args:
146
+ api_url: Base API URL
147
+
148
+ Returns:
149
+ Function to make JSON-RPC requests
150
+ """
151
+ def make_request(method: str, params: Dict[str, Any], request_id: int = 1) -> Dict[str, Any]:
152
+ """
153
+ Make a JSON-RPC request.
154
+
155
+ Args:
156
+ method: Method name
157
+ params: Method parameters
158
+ request_id: Request ID
159
+
160
+ Returns:
161
+ JSON-RPC response
162
+ """
163
+ payload = {
164
+ "jsonrpc": "2.0",
165
+ "method": method,
166
+ "params": params,
167
+ "id": request_id
168
+ }
169
+
170
+ response = requests.post(
171
+ f"{api_url}/api/jsonrpc",
172
+ json=payload,
173
+ headers={"Content-Type": "application/json"}
174
+ )
175
+
176
+ return response.json()
177
+
178
+ return make_request
179
+
180
+
181
+ @pytest.fixture
182
+ def batch_jsonrpc_client(api_url: str) -> Callable:
183
+ """
184
+ Fixture that provides a batch JSON-RPC client function.
185
+
186
+ Args:
187
+ api_url: Base API URL
188
+
189
+ Returns:
190
+ Function to make batch JSON-RPC requests
191
+ """
192
+ def make_batch_request(requests_data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
193
+ """
194
+ Make a batch JSON-RPC request.
195
+
196
+ Args:
197
+ requests_data: List of request objects
198
+
199
+ Returns:
200
+ List of JSON-RPC responses
201
+ """
202
+ response = requests.post(
203
+ f"{api_url}/api/jsonrpc",
204
+ json=requests_data,
205
+ headers={"Content-Type": "application/json"}
206
+ )
207
+
208
+ return response.json()
209
+
210
+ return make_batch_request
211
+
212
+
213
+ @pytest.fixture
214
+ def echo_command() -> EchoCommand:
215
+ """
216
+ Fixture that provides an instance of EchoCommand.
217
+
218
+ Returns:
219
+ EchoCommand instance
220
+ """
221
+ return EchoCommand()
222
+
223
+
224
+ @pytest.fixture
225
+ def math_command() -> MathCommand:
226
+ """
227
+ Fixture that provides an instance of MathCommand.
228
+
229
+ Returns:
230
+ MathCommand instance
231
+ """
232
+ return MathCommand()
233
+
234
+
235
+ @pytest.fixture
236
+ def time_command() -> TimeCommand:
237
+ """
238
+ Fixture that provides an instance of TimeCommand.
239
+
240
+ Returns:
241
+ TimeCommand instance
242
+ """
243
+ return TimeCommand()
@@ -0,0 +1,52 @@
1
+ """
2
+ Module with echo command implementation.
3
+ """
4
+
5
+ from typing import Any, Dict, Optional, ClassVar, Type
6
+
7
+ from pydantic import BaseModel, Field, ValidationError as PydanticValidationError
8
+
9
+ from mcp_proxy_adapter.commands.base import Command
10
+ from examples.commands.echo_result import EchoResult
11
+ from mcp_proxy_adapter.core.errors import ValidationError
12
+ from mcp_proxy_adapter.core.logging import logger
13
+
14
+
15
+ class EchoCommand(Command):
16
+ """
17
+ Command that echoes back the parameters it receives.
18
+
19
+ This command is useful for testing parameter passing and debugging.
20
+ """
21
+
22
+ name: ClassVar[str] = "echo"
23
+ result_class: ClassVar[Type[EchoResult]] = EchoResult
24
+
25
+ @classmethod
26
+ def get_schema(cls) -> Dict[str, Any]:
27
+ """
28
+ Returns JSON schema for command parameters validation.
29
+
30
+ Returns:
31
+ Dictionary with JSON schema.
32
+ """
33
+ return {
34
+ "type": "object",
35
+ "additionalProperties": True,
36
+ "description": "Any parameters will be echoed back in the response"
37
+ }
38
+
39
+ async def execute(self, **kwargs) -> EchoResult:
40
+ """
41
+ Executes echo command and returns the parameters back.
42
+
43
+ Args:
44
+ **kwargs: Any parameters to echo back.
45
+
46
+ Returns:
47
+ EchoResult: Command execution result with the parameters.
48
+ """
49
+ logger.debug(f"Echo command received parameters: {kwargs}")
50
+
51
+ # Simply return the parameters that were passed
52
+ return EchoResult(params=kwargs)