mcp-proxy-adapter 2.1.17__py3-none-any.whl → 3.0.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 (135) 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 +245 -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 +25 -0
  14. examples/basic_example/docs/EN/README.md +177 -0
  15. examples/basic_example/docs/RU/README.md +177 -0
  16. examples/basic_example/server.py +151 -0
  17. examples/basic_example/tests/conftest.py +243 -0
  18. examples/commands/echo_command.py +52 -0
  19. examples/commands/echo_result.py +65 -0
  20. examples/commands/get_date_command.py +98 -0
  21. examples/commands/new_uuid4_command.py +91 -0
  22. examples/complete_example/Dockerfile +24 -0
  23. examples/complete_example/README.md +92 -0
  24. examples/complete_example/__init__.py +8 -0
  25. examples/complete_example/commands/__init__.py +5 -0
  26. examples/complete_example/commands/system_command.py +328 -0
  27. examples/complete_example/config.json +41 -0
  28. examples/complete_example/configs/config.dev.yaml +40 -0
  29. examples/complete_example/configs/config.docker.yaml +40 -0
  30. examples/complete_example/docker-compose.yml +35 -0
  31. examples/complete_example/requirements.txt +20 -0
  32. examples/complete_example/server.py +139 -0
  33. examples/minimal_example/README.md +65 -0
  34. examples/minimal_example/__init__.py +8 -0
  35. examples/minimal_example/config.json +14 -0
  36. examples/minimal_example/main.py +136 -0
  37. examples/minimal_example/simple_server.py +163 -0
  38. examples/minimal_example/tests/conftest.py +171 -0
  39. examples/minimal_example/tests/test_hello_command.py +111 -0
  40. examples/minimal_example/tests/test_integration.py +181 -0
  41. examples/server.py +69 -0
  42. examples/simple_server.py +128 -0
  43. examples/test_server.py +134 -0
  44. examples/tool_description_example.py +82 -0
  45. mcp_proxy_adapter/__init__.py +33 -1
  46. mcp_proxy_adapter/api/__init__.py +0 -0
  47. mcp_proxy_adapter/api/app.py +391 -0
  48. mcp_proxy_adapter/api/handlers.py +229 -0
  49. mcp_proxy_adapter/api/middleware/__init__.py +49 -0
  50. mcp_proxy_adapter/api/middleware/auth.py +146 -0
  51. mcp_proxy_adapter/api/middleware/base.py +79 -0
  52. mcp_proxy_adapter/api/middleware/error_handling.py +198 -0
  53. mcp_proxy_adapter/api/middleware/logging.py +96 -0
  54. mcp_proxy_adapter/api/middleware/performance.py +83 -0
  55. mcp_proxy_adapter/api/middleware/rate_limit.py +152 -0
  56. mcp_proxy_adapter/api/schemas.py +305 -0
  57. mcp_proxy_adapter/api/tool_integration.py +223 -0
  58. mcp_proxy_adapter/api/tools.py +198 -0
  59. mcp_proxy_adapter/commands/__init__.py +19 -0
  60. mcp_proxy_adapter/commands/base.py +301 -0
  61. mcp_proxy_adapter/commands/command_registry.py +231 -0
  62. mcp_proxy_adapter/commands/config_command.py +113 -0
  63. mcp_proxy_adapter/commands/health_command.py +136 -0
  64. mcp_proxy_adapter/commands/help_command.py +193 -0
  65. mcp_proxy_adapter/commands/result.py +215 -0
  66. mcp_proxy_adapter/config.py +195 -0
  67. mcp_proxy_adapter/core/__init__.py +0 -0
  68. mcp_proxy_adapter/core/errors.py +173 -0
  69. mcp_proxy_adapter/core/logging.py +205 -0
  70. mcp_proxy_adapter/core/utils.py +138 -0
  71. mcp_proxy_adapter/custom_openapi.py +125 -0
  72. mcp_proxy_adapter/openapi.py +403 -0
  73. mcp_proxy_adapter/py.typed +0 -0
  74. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  75. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  76. mcp_proxy_adapter/tests/__init__.py +0 -0
  77. mcp_proxy_adapter/tests/api/__init__.py +3 -0
  78. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +115 -0
  79. mcp_proxy_adapter/tests/api/test_middleware.py +336 -0
  80. mcp_proxy_adapter/tests/commands/__init__.py +3 -0
  81. mcp_proxy_adapter/tests/commands/test_config_command.py +211 -0
  82. mcp_proxy_adapter/tests/commands/test_echo_command.py +127 -0
  83. mcp_proxy_adapter/tests/commands/test_help_command.py +133 -0
  84. mcp_proxy_adapter/tests/conftest.py +131 -0
  85. mcp_proxy_adapter/tests/functional/__init__.py +3 -0
  86. mcp_proxy_adapter/tests/functional/test_api.py +235 -0
  87. mcp_proxy_adapter/tests/integration/__init__.py +3 -0
  88. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +130 -0
  89. mcp_proxy_adapter/tests/integration/test_integration.py +255 -0
  90. mcp_proxy_adapter/tests/performance/__init__.py +3 -0
  91. mcp_proxy_adapter/tests/performance/test_performance.py +189 -0
  92. mcp_proxy_adapter/tests/stubs/__init__.py +10 -0
  93. mcp_proxy_adapter/tests/stubs/echo_command.py +104 -0
  94. mcp_proxy_adapter/tests/test_api_endpoints.py +271 -0
  95. mcp_proxy_adapter/tests/test_api_handlers.py +289 -0
  96. mcp_proxy_adapter/tests/test_base_command.py +123 -0
  97. mcp_proxy_adapter/tests/test_batch_requests.py +117 -0
  98. mcp_proxy_adapter/tests/test_command_registry.py +245 -0
  99. mcp_proxy_adapter/tests/test_config.py +127 -0
  100. mcp_proxy_adapter/tests/test_utils.py +65 -0
  101. mcp_proxy_adapter/tests/unit/__init__.py +3 -0
  102. mcp_proxy_adapter/tests/unit/test_base_command.py +130 -0
  103. mcp_proxy_adapter/tests/unit/test_config.py +217 -0
  104. mcp_proxy_adapter/version.py +3 -0
  105. mcp_proxy_adapter-3.0.1.dist-info/METADATA +200 -0
  106. mcp_proxy_adapter-3.0.1.dist-info/RECORD +109 -0
  107. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/top_level.txt +1 -0
  108. mcp_proxy_adapter/adapter.py +0 -697
  109. mcp_proxy_adapter/analyzers/__init__.py +0 -1
  110. mcp_proxy_adapter/analyzers/docstring_analyzer.py +0 -199
  111. mcp_proxy_adapter/analyzers/type_analyzer.py +0 -151
  112. mcp_proxy_adapter/dispatchers/__init__.py +0 -1
  113. mcp_proxy_adapter/dispatchers/base_dispatcher.py +0 -85
  114. mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py +0 -262
  115. mcp_proxy_adapter/examples/analyze_config.py +0 -141
  116. mcp_proxy_adapter/examples/basic_integration.py +0 -155
  117. mcp_proxy_adapter/examples/docstring_and_schema_example.py +0 -69
  118. mcp_proxy_adapter/examples/extension_example.py +0 -72
  119. mcp_proxy_adapter/examples/help_best_practices.py +0 -67
  120. mcp_proxy_adapter/examples/help_usage.py +0 -64
  121. mcp_proxy_adapter/examples/mcp_proxy_client.py +0 -131
  122. mcp_proxy_adapter/examples/openapi_server.py +0 -383
  123. mcp_proxy_adapter/examples/project_structure_example.py +0 -47
  124. mcp_proxy_adapter/examples/testing_example.py +0 -64
  125. mcp_proxy_adapter/models.py +0 -47
  126. mcp_proxy_adapter/registry.py +0 -439
  127. mcp_proxy_adapter/schema.py +0 -257
  128. mcp_proxy_adapter/testing_utils.py +0 -112
  129. mcp_proxy_adapter/validators/__init__.py +0 -1
  130. mcp_proxy_adapter/validators/docstring_validator.py +0 -75
  131. mcp_proxy_adapter/validators/metadata_validator.py +0 -76
  132. mcp_proxy_adapter-2.1.17.dist-info/METADATA +0 -376
  133. mcp_proxy_adapter-2.1.17.dist-info/RECORD +0 -30
  134. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/WHEEL +0 -0
  135. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,181 @@
1
+ """
2
+ Integration tests for the minimal example of MCP Proxy Adapter.
3
+
4
+ These tests start a real server instance and test the API endpoints.
5
+ """
6
+
7
+ import os
8
+ import time
9
+ import pytest
10
+ import requests
11
+ from typing import Dict, Any, Callable
12
+
13
+ from conftest import ServerProcess
14
+
15
+
16
+ class TestHelloCommandIntegration:
17
+ """Integration tests for the HelloCommand API."""
18
+
19
+ def test_jsonrpc_hello_default(self, server: ServerProcess, jsonrpc_client: Callable):
20
+ """Test the hello command via JSON-RPC with default parameters."""
21
+ # Make JSON-RPC request
22
+ response = jsonrpc_client("hello", {})
23
+
24
+ # Check response
25
+ assert "jsonrpc" in response
26
+ assert response["jsonrpc"] == "2.0"
27
+ assert "id" in response
28
+ assert "result" in response
29
+ assert "message" in response["result"]
30
+ assert response["result"]["message"] == "Hello, World!"
31
+
32
+ def test_jsonrpc_hello_custom_name(self, server: ServerProcess, jsonrpc_client: Callable):
33
+ """Test the hello command via JSON-RPC with custom name parameter."""
34
+ # Make JSON-RPC request
35
+ response = jsonrpc_client("hello", {"name": "Integration Test"})
36
+
37
+ # Check response
38
+ assert "result" in response
39
+ assert "message" in response["result"]
40
+ assert response["result"]["message"] == "Hello, Integration Test!"
41
+
42
+ def test_cmd_endpoint_hello(self, server: ServerProcess, api_url: str):
43
+ """Test the hello command via the /cmd endpoint."""
44
+ # Prepare request
45
+ payload = {
46
+ "command": "hello",
47
+ "params": {"name": "CMD Endpoint"}
48
+ }
49
+
50
+ # Make request
51
+ response = requests.post(
52
+ f"{api_url}/cmd",
53
+ json=payload,
54
+ headers={"Content-Type": "application/json"}
55
+ )
56
+
57
+ # Check response
58
+ assert response.status_code == 200
59
+ data = response.json()
60
+ assert "result" in data
61
+ assert "message" in data["result"]
62
+ assert data["result"]["message"] == "Hello, CMD Endpoint!"
63
+
64
+ def test_api_command_endpoint_hello(self, server: ServerProcess, api_url: str):
65
+ """Test the hello command via the /api/command/{command_name} endpoint."""
66
+ # Prepare params
67
+ params = {"name": "API Command Endpoint"}
68
+
69
+ # Make request
70
+ response = requests.post(
71
+ f"{api_url}/api/command/hello",
72
+ json=params,
73
+ headers={"Content-Type": "application/json"}
74
+ )
75
+
76
+ # Check response
77
+ assert response.status_code == 200
78
+ data = response.json()
79
+ assert "message" in data
80
+ assert data["message"] == "Hello, API Command Endpoint!"
81
+
82
+ def test_jsonrpc_batch_request(self, server: ServerProcess, api_url: str):
83
+ """Test batch JSON-RPC requests with hello command."""
84
+ # Prepare batch request
85
+ batch = [
86
+ {
87
+ "jsonrpc": "2.0",
88
+ "method": "hello",
89
+ "params": {"name": "Batch 1"},
90
+ "id": 1
91
+ },
92
+ {
93
+ "jsonrpc": "2.0",
94
+ "method": "hello",
95
+ "params": {"name": "Batch 2"},
96
+ "id": 2
97
+ }
98
+ ]
99
+
100
+ # Make request
101
+ response = requests.post(
102
+ f"{api_url}/api/jsonrpc",
103
+ json=batch,
104
+ headers={"Content-Type": "application/json"}
105
+ )
106
+
107
+ # Check response
108
+ assert response.status_code == 200
109
+ data = response.json()
110
+ assert isinstance(data, list)
111
+ assert len(data) == 2
112
+
113
+ # Check first result
114
+ assert data[0]["id"] == 1
115
+ assert data[0]["result"]["message"] == "Hello, Batch 1!"
116
+
117
+ # Check second result
118
+ assert data[1]["id"] == 2
119
+ assert data[1]["result"]["message"] == "Hello, Batch 2!"
120
+
121
+
122
+ class TestServerIntegration:
123
+ """Integration tests for the server itself."""
124
+
125
+ def test_health_endpoint(self, server: ServerProcess, api_url: str):
126
+ """Test the /health endpoint."""
127
+ response = requests.get(f"{api_url}/health")
128
+
129
+ # Check response
130
+ assert response.status_code == 200
131
+ data = response.json()
132
+ assert "status" in data
133
+ assert data["status"] == "ok"
134
+
135
+ def test_openapi_schema(self, server: ServerProcess, api_url: str):
136
+ """Test the OpenAPI schema endpoint."""
137
+ response = requests.get(f"{api_url}/openapi.json")
138
+
139
+ # Check response
140
+ assert response.status_code == 200
141
+ schema = response.json()
142
+
143
+ # Check schema structure
144
+ assert "openapi" in schema
145
+ assert "info" in schema
146
+ assert "paths" in schema
147
+
148
+ # Проверяем наличие основных эндпоинтов
149
+ assert "/api/jsonrpc" in schema["paths"] or "/cmd" in schema["paths"]
150
+ assert "/api/commands" in schema["paths"]
151
+
152
+ def test_docs_endpoint(self, server: ServerProcess, api_url: str):
153
+ """Test the Swagger UI endpoint."""
154
+ response = requests.get(f"{api_url}/docs")
155
+
156
+ # Check response
157
+ assert response.status_code == 200
158
+ assert "text/html" in response.headers["Content-Type"]
159
+
160
+ # Check if swagger UI is in the response
161
+ assert "swagger-ui" in response.text.lower()
162
+
163
+ def test_commands_list_endpoint(self, server: ServerProcess, api_url: str):
164
+ """Test the commands list endpoint."""
165
+ response = requests.get(f"{api_url}/api/commands")
166
+
167
+ # Check response
168
+ assert response.status_code == 200
169
+ data = response.json()
170
+
171
+ # Check data structure
172
+ assert "commands" in data
173
+ assert isinstance(data["commands"], dict) # Теперь commands это словарь, а не список
174
+
175
+ # Check if hello command is in the list
176
+ assert "hello" in data["commands"]
177
+
178
+ # Check hello command details
179
+ hello_cmd = data["commands"]["hello"]
180
+ assert "name" in hello_cmd
181
+ assert hello_cmd["name"] == "hello"
examples/server.py ADDED
@@ -0,0 +1,69 @@
1
+ """
2
+ Main application module.
3
+ """
4
+
5
+ import os
6
+ import sys
7
+ import uvicorn
8
+ import logging
9
+
10
+ from mcp_proxy_adapter import create_app
11
+
12
+ app = create_app()
13
+ from mcp_proxy_adapter.config import config
14
+ from mcp_proxy_adapter.core.logging import logger, setup_logging
15
+
16
+
17
+ def main():
18
+ """
19
+ Main function to run the application.
20
+ """
21
+ # Убедимся что логирование настроено
22
+ logger.info("Initializing logging configuration")
23
+
24
+ try:
25
+ # Получаем настройки логирования
26
+ log_level = config.get("logging.level", "INFO")
27
+ log_file = config.get("logging.file")
28
+ rotation_type = config.get("logging.rotation.type", "size")
29
+
30
+ # Выводим информацию о настройках логирования
31
+ logger.info(f"Log level: {log_level}")
32
+ if log_file:
33
+ logger.info(f"Log file: {log_file}")
34
+ logger.info(f"Log rotation type: {rotation_type}")
35
+
36
+ if rotation_type.lower() == "time":
37
+ when = config.get("logging.rotation.when", "D")
38
+ interval = config.get("logging.rotation.interval", 1)
39
+ logger.info(f"Log rotation: every {interval} {when}")
40
+ else:
41
+ max_bytes = config.get("logging.rotation.max_bytes", 10 * 1024 * 1024)
42
+ logger.info(f"Log rotation: when size reaches {max_bytes / (1024*1024):.1f} MB")
43
+
44
+ backup_count = config.get("logging.rotation.backup_count", 5)
45
+ logger.info(f"Log backups: {backup_count}")
46
+ else:
47
+ logger.info("File logging is disabled")
48
+
49
+ # Get server settings
50
+ host = config.get("server.host", "0.0.0.0")
51
+ port = config.get("server.port", 8000)
52
+
53
+ logger.info(f"Starting server on {host}:{port}")
54
+
55
+ # Run server
56
+ uvicorn.run(
57
+ "mcp_proxy_adapter.api.app:app",
58
+ host=host,
59
+ port=port,
60
+ reload=True if os.environ.get("DEBUG") else False,
61
+ log_level=log_level.lower()
62
+ )
63
+ except Exception as e:
64
+ logger.exception(f"Error during application startup: {e}")
65
+ sys.exit(1)
66
+
67
+
68
+ if __name__ == "__main__":
69
+ main()
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Простой пример запуска сервера JSON-RPC с использованием MCP Proxy Adapter.
4
+
5
+ Этот скрипт демонстрирует минимальную конфигурацию для запуска сервера JSON-RPC.
6
+ Он создаёт экземпляр приложения FastAPI с MCP Proxy Adapter и регистрирует пользовательские команды.
7
+ """
8
+
9
+ import os
10
+ import argparse
11
+ import sys
12
+ from pathlib import Path
13
+ import uvicorn
14
+
15
+ # Добавляем родительскую директорию в PYTHONPATH для импорта mcp_proxy_adapter
16
+ sys.path.insert(0, str(Path(__file__).parent.parent))
17
+
18
+ from mcp_proxy_adapter import Command, SuccessResult, create_app
19
+ from mcp_proxy_adapter.commands.command_registry import registry
20
+ from typing import Dict, Any, Optional
21
+
22
+
23
+ class HelloResult(SuccessResult):
24
+ """Result of hello command."""
25
+
26
+ def __init__(self, message: str):
27
+ """
28
+ Initialize result.
29
+
30
+ Args:
31
+ message: Hello message
32
+ """
33
+ self.message = message
34
+
35
+ def to_dict(self) -> Dict[str, Any]:
36
+ """
37
+ Convert result to dictionary.
38
+
39
+ Returns:
40
+ Dictionary representation
41
+ """
42
+ return {"message": self.message}
43
+
44
+ @classmethod
45
+ def get_schema(cls) -> Dict[str, Any]:
46
+ """
47
+ Get JSON schema for result.
48
+
49
+ Returns:
50
+ JSON schema
51
+ """
52
+ return {
53
+ "type": "object",
54
+ "properties": {
55
+ "message": {"type": "string"}
56
+ },
57
+ "required": ["message"]
58
+ }
59
+
60
+
61
+ class HelloCommand(Command):
62
+ """Command that returns hello message."""
63
+
64
+ name = "hello"
65
+ result_class = HelloResult
66
+
67
+ async def execute(self, name: str = "World") -> HelloResult:
68
+ """
69
+ Execute command.
70
+
71
+ Args:
72
+ name: Name to greet
73
+
74
+ Returns:
75
+ Hello result
76
+ """
77
+ return HelloResult(f"Hello, {name}!")
78
+
79
+ @classmethod
80
+ def get_schema(cls) -> Dict[str, Any]:
81
+ """
82
+ Get JSON schema for command parameters.
83
+
84
+ Returns:
85
+ JSON schema
86
+ """
87
+ return {
88
+ "type": "object",
89
+ "properties": {
90
+ "name": {"type": "string"}
91
+ },
92
+ "additionalProperties": False
93
+ }
94
+
95
+
96
+ def main():
97
+ """
98
+ Основная функция для запуска сервера.
99
+ """
100
+ parser = argparse.ArgumentParser(description="JSON-RPC Microservice Server")
101
+ parser.add_argument("--host", default="0.0.0.0", help="Host to bind server")
102
+ parser.add_argument("--port", type=int, default=8000, help="Port to bind server")
103
+ parser.add_argument("--reload", action="store_true", help="Enable auto-reload")
104
+
105
+ args = parser.parse_args()
106
+
107
+ # Регистрируем только свою пользовательскую команду
108
+ # встроенные команды и примеры регистрируются автоматически
109
+ registry.register(HelloCommand)
110
+
111
+ # Создаем приложение FastAPI
112
+ app = create_app()
113
+
114
+ # Запускаем сервер
115
+ uvicorn.run(
116
+ app,
117
+ host=args.host,
118
+ port=args.port,
119
+ reload=args.reload
120
+ )
121
+
122
+
123
+ if __name__ == "__main__":
124
+ # Run the simple server example
125
+ # To test, open http://localhost:8000/docs in your browser
126
+ # or use curl:
127
+ # curl -X POST http://localhost:8000/api/cmd -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"hello","params":{"name":"PyPI"},"id":1}'
128
+ main()
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Тестовый скрипт для запуска сервера JSON-RPC с использованием MCP Proxy Adapter.
4
+ Использует только базовую команду для тестирования установки пакета.
5
+ """
6
+
7
+ import os
8
+ import argparse
9
+ import sys
10
+ import uvicorn
11
+ from pathlib import Path
12
+ from typing import Dict, Any, Optional
13
+
14
+ # Добавляем родительскую директорию в PYTHONPATH для импорта mcp_proxy_adapter
15
+ sys.path.insert(0, str(Path(__file__).parent.parent))
16
+
17
+ from mcp_proxy_adapter import Command, SuccessResult, create_app, registry
18
+ from mcp_proxy_adapter.core.logging import setup_logging
19
+ from mcp_proxy_adapter.config import config
20
+
21
+
22
+ class HelloResult(SuccessResult):
23
+ """Result of hello command."""
24
+
25
+ def __init__(self, message: str):
26
+ """
27
+ Initialize result.
28
+
29
+ Args:
30
+ message: Hello message
31
+ """
32
+ self.message = message
33
+
34
+ def to_dict(self) -> Dict[str, Any]:
35
+ """
36
+ Convert result to dictionary.
37
+
38
+ Returns:
39
+ Dictionary representation
40
+ """
41
+ return {"message": self.message}
42
+
43
+ @classmethod
44
+ def get_schema(cls) -> Dict[str, Any]:
45
+ """
46
+ Get JSON schema for result.
47
+
48
+ Returns:
49
+ JSON schema
50
+ """
51
+ return {
52
+ "type": "object",
53
+ "properties": {
54
+ "message": {"type": "string"}
55
+ },
56
+ "required": ["message"]
57
+ }
58
+
59
+
60
+ class HelloCommand(Command):
61
+ """Command that returns hello message."""
62
+
63
+ name = "hello"
64
+ result_class = HelloResult
65
+
66
+ async def execute(self, name: str = "World") -> HelloResult:
67
+ """
68
+ Execute command.
69
+
70
+ Args:
71
+ name: Name to greet
72
+
73
+ Returns:
74
+ Hello result
75
+ """
76
+ return HelloResult(f"Hello, {name}!")
77
+
78
+ @classmethod
79
+ def get_schema(cls) -> Dict[str, Any]:
80
+ """
81
+ Get JSON schema for command parameters.
82
+
83
+ Returns:
84
+ JSON schema
85
+ """
86
+ return {
87
+ "type": "object",
88
+ "properties": {
89
+ "name": {"type": "string"}
90
+ },
91
+ "additionalProperties": False
92
+ }
93
+
94
+
95
+ def main():
96
+ """
97
+ Основная функция для запуска сервера.
98
+ """
99
+ parser = argparse.ArgumentParser(description="Test JSON-RPC Microservice Server")
100
+ parser.add_argument("--host", default="0.0.0.0", help="Host to bind server")
101
+ parser.add_argument("--port", type=int, default=8000, help="Port to bind server")
102
+ parser.add_argument("--reload", action="store_true", help="Enable auto-reload")
103
+ parser.add_argument("--config", help="Path to config file")
104
+
105
+ args = parser.parse_args()
106
+
107
+ # Инициализируем конфигурацию
108
+ if args.config and os.path.exists(args.config):
109
+ config.load_from_file(args.config)
110
+
111
+ # Настраиваем логирование
112
+ setup_logging("INFO")
113
+
114
+ # Создаем приложение FastAPI
115
+ app = create_app()
116
+ app.title = "Test Microservice"
117
+ app.description = "Test microservice for package installation verification"
118
+ app.version = "1.0.0"
119
+
120
+ # Регистрируем только одну команду для тестирования
121
+ registry.register(HelloCommand)
122
+
123
+ # Запускаем сервер
124
+ uvicorn.run(
125
+ app,
126
+ host=args.host,
127
+ port=args.port,
128
+ reload=args.reload,
129
+ log_level="info"
130
+ )
131
+
132
+
133
+ if __name__ == "__main__":
134
+ main()
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ Example of using the API tool description functionality.
4
+
5
+ This script demonstrates how to use the API tool description functionality
6
+ to generate rich and informative descriptions for API tools.
7
+ """
8
+
9
+ import json
10
+ import asyncio
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ # Add the project root to the Python path
15
+ sys.path.insert(0, str(Path(__file__).parent.parent))
16
+
17
+ from mcp_proxy_adapter.commands.command_registry import registry
18
+ from mcp_proxy_adapter.api.schemas import APIToolDescription
19
+ from mcp_proxy_adapter.api.tools import get_tool_description, TSTCommandExecutor
20
+ from mcp_proxy_adapter.commands.help_command import HelpCommand
21
+
22
+
23
+ async def main():
24
+ """Main function to demonstrate API tool description functionality."""
25
+
26
+ # Register the help command so we have at least one command registered
27
+ if not registry.command_exists("help"):
28
+ registry.register(HelpCommand)
29
+
30
+ # Generate description using the APIToolDescription class directly
31
+ print("Generating tool description using APIToolDescription:")
32
+ description = APIToolDescription.generate_tool_description("tst_execute_command", registry)
33
+ print(json.dumps(description, indent=2, ensure_ascii=False))
34
+ print("\n" + "-" * 80 + "\n")
35
+
36
+ # Generate text description using the APIToolDescription class
37
+ print("Generating tool description text using APIToolDescription:")
38
+ description_text = APIToolDescription.generate_tool_description_text("tst_execute_command", registry)
39
+ print(description_text)
40
+ print("\n" + "-" * 80 + "\n")
41
+
42
+ # Get tool description using the tools module
43
+ print("Getting tool description using the tools module:")
44
+ tool_description = get_tool_description("tst_execute_command")
45
+ print(json.dumps(tool_description, indent=2, ensure_ascii=False))
46
+ print("\n" + "-" * 80 + "\n")
47
+
48
+ # Get tool description in markdown format using the tools module
49
+ print("Getting tool description in markdown format using the tools module:")
50
+ tool_description_md = get_tool_description("tst_execute_command", "markdown")
51
+ print(tool_description_md)
52
+ print("\n" + "-" * 80 + "\n")
53
+
54
+ # Get tool schema directly from the tool class
55
+ print("Getting tool schema directly from the tool class:")
56
+ tool_schema = TSTCommandExecutor.get_schema()
57
+ print(json.dumps(tool_schema, indent=2, ensure_ascii=False))
58
+ print("\n" + "-" * 80 + "\n")
59
+
60
+ # Get tool description directly from the tool class
61
+ print("Getting tool description directly from the tool class:")
62
+ tool_desc = TSTCommandExecutor.get_description("json")
63
+ print(json.dumps(tool_desc, indent=2, ensure_ascii=False))
64
+ print("\n" + "-" * 80 + "\n")
65
+
66
+ # Show how this can be used to create informative command-line help
67
+ print("Example command-line help based on tool description:")
68
+ help_text = f"""
69
+ {TSTCommandExecutor.name} - {TSTCommandExecutor.description}
70
+
71
+ Available commands:
72
+ """
73
+
74
+ for cmd_name in tool_schema["parameters"]["properties"]["command"]["enum"]:
75
+ cmd_info = description["supported_commands"].get(cmd_name, {})
76
+ help_text += f" {cmd_name} - {cmd_info.get('summary', '')}\n"
77
+
78
+ print(help_text)
79
+
80
+
81
+ if __name__ == "__main__":
82
+ asyncio.run(main())
@@ -1 +1,33 @@
1
-
1
+ """MCP Proxy API Service package.
2
+
3
+ This package provides a framework for creating JSON-RPC-enabled microservices.
4
+ """
5
+
6
+ from mcp_proxy_adapter.version import __version__
7
+ from mcp_proxy_adapter.api.app import create_app
8
+ from mcp_proxy_adapter.commands.base import Command
9
+ from mcp_proxy_adapter.commands.result import CommandResult, SuccessResult, ErrorResult
10
+ from mcp_proxy_adapter.commands.command_registry import registry
11
+ from mcp_proxy_adapter.core.errors import (
12
+ MicroserviceError, CommandError, ValidationError,
13
+ InvalidParamsError, NotFoundError, TimeoutError,
14
+ InternalError
15
+ )
16
+
17
+ # Экспортируем основные классы и функции для удобного использования
18
+ __all__ = [
19
+ "__version__",
20
+ "create_app",
21
+ "Command",
22
+ "CommandResult",
23
+ "SuccessResult",
24
+ "ErrorResult",
25
+ "registry",
26
+ "MicroserviceError",
27
+ "CommandError",
28
+ "ValidationError",
29
+ "InvalidParamsError",
30
+ "NotFoundError",
31
+ "TimeoutError",
32
+ "InternalError"
33
+ ]
File without changes