mcp-proxy-adapter 3.0.0__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 (84) hide show
  1. examples/basic_example/README.md +123 -9
  2. examples/basic_example/config.json +4 -0
  3. examples/basic_example/docs/EN/README.md +46 -5
  4. examples/basic_example/docs/RU/README.md +46 -5
  5. examples/basic_example/server.py +127 -21
  6. examples/complete_example/commands/system_command.py +1 -0
  7. examples/complete_example/server.py +65 -11
  8. examples/minimal_example/README.md +20 -6
  9. examples/minimal_example/config.json +7 -14
  10. examples/minimal_example/main.py +109 -40
  11. examples/minimal_example/simple_server.py +53 -14
  12. examples/minimal_example/tests/conftest.py +1 -1
  13. examples/minimal_example/tests/test_integration.py +8 -10
  14. examples/simple_server.py +12 -21
  15. examples/test_server.py +22 -14
  16. examples/tool_description_example.py +82 -0
  17. mcp_proxy_adapter/api/__init__.py +0 -0
  18. mcp_proxy_adapter/api/app.py +391 -0
  19. mcp_proxy_adapter/api/handlers.py +229 -0
  20. mcp_proxy_adapter/api/middleware/__init__.py +49 -0
  21. mcp_proxy_adapter/api/middleware/auth.py +146 -0
  22. mcp_proxy_adapter/api/middleware/base.py +79 -0
  23. mcp_proxy_adapter/api/middleware/error_handling.py +198 -0
  24. mcp_proxy_adapter/api/middleware/logging.py +96 -0
  25. mcp_proxy_adapter/api/middleware/performance.py +83 -0
  26. mcp_proxy_adapter/api/middleware/rate_limit.py +152 -0
  27. mcp_proxy_adapter/api/schemas.py +305 -0
  28. mcp_proxy_adapter/api/tool_integration.py +223 -0
  29. mcp_proxy_adapter/api/tools.py +198 -0
  30. mcp_proxy_adapter/commands/__init__.py +19 -0
  31. mcp_proxy_adapter/commands/base.py +301 -0
  32. mcp_proxy_adapter/commands/command_registry.py +231 -0
  33. mcp_proxy_adapter/commands/config_command.py +113 -0
  34. mcp_proxy_adapter/commands/health_command.py +136 -0
  35. mcp_proxy_adapter/commands/help_command.py +193 -0
  36. mcp_proxy_adapter/commands/result.py +215 -0
  37. mcp_proxy_adapter/config.py +9 -0
  38. mcp_proxy_adapter/core/__init__.py +0 -0
  39. mcp_proxy_adapter/core/errors.py +173 -0
  40. mcp_proxy_adapter/core/logging.py +205 -0
  41. mcp_proxy_adapter/core/utils.py +138 -0
  42. mcp_proxy_adapter/py.typed +0 -0
  43. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  44. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  45. mcp_proxy_adapter/tests/__init__.py +0 -0
  46. mcp_proxy_adapter/tests/api/__init__.py +3 -0
  47. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +115 -0
  48. mcp_proxy_adapter/tests/api/test_middleware.py +336 -0
  49. mcp_proxy_adapter/tests/commands/__init__.py +3 -0
  50. mcp_proxy_adapter/tests/commands/test_config_command.py +211 -0
  51. mcp_proxy_adapter/tests/commands/test_echo_command.py +127 -0
  52. mcp_proxy_adapter/tests/commands/test_help_command.py +133 -0
  53. mcp_proxy_adapter/tests/conftest.py +131 -0
  54. mcp_proxy_adapter/tests/functional/__init__.py +3 -0
  55. mcp_proxy_adapter/tests/functional/test_api.py +235 -0
  56. mcp_proxy_adapter/tests/integration/__init__.py +3 -0
  57. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +130 -0
  58. mcp_proxy_adapter/tests/integration/test_integration.py +255 -0
  59. mcp_proxy_adapter/tests/performance/__init__.py +3 -0
  60. mcp_proxy_adapter/tests/performance/test_performance.py +189 -0
  61. mcp_proxy_adapter/tests/stubs/__init__.py +10 -0
  62. mcp_proxy_adapter/tests/stubs/echo_command.py +104 -0
  63. mcp_proxy_adapter/tests/test_api_endpoints.py +271 -0
  64. mcp_proxy_adapter/tests/test_api_handlers.py +289 -0
  65. mcp_proxy_adapter/tests/test_base_command.py +123 -0
  66. mcp_proxy_adapter/tests/test_batch_requests.py +117 -0
  67. mcp_proxy_adapter/tests/test_command_registry.py +245 -0
  68. mcp_proxy_adapter/tests/test_config.py +127 -0
  69. mcp_proxy_adapter/tests/test_utils.py +65 -0
  70. mcp_proxy_adapter/tests/unit/__init__.py +3 -0
  71. mcp_proxy_adapter/tests/unit/test_base_command.py +130 -0
  72. mcp_proxy_adapter/tests/unit/test_config.py +217 -0
  73. mcp_proxy_adapter/version.py +1 -1
  74. {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/METADATA +1 -1
  75. mcp_proxy_adapter-3.0.1.dist-info/RECORD +109 -0
  76. examples/basic_example/config.yaml +0 -20
  77. examples/basic_example/main.py +0 -50
  78. examples/complete_example/main.py +0 -67
  79. examples/minimal_example/config.yaml +0 -26
  80. mcp_proxy_adapter/framework.py +0 -109
  81. mcp_proxy_adapter-3.0.0.dist-info/RECORD +0 -58
  82. {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/WHEEL +0 -0
  83. {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/licenses/LICENSE +0 -0
  84. {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/top_level.txt +0 -0
@@ -1,63 +1,132 @@
1
1
  """
2
- Main application module.
2
+ Минимальный пример приложения MCP Proxy Adapter.
3
3
  """
4
4
 
5
5
  import os
6
6
  import sys
7
7
  import uvicorn
8
8
  import logging
9
+ import json
10
+ from pathlib import Path
9
11
 
10
- from mcp_proxy_adapter.api.app import app
12
+ from mcp_proxy_adapter import create_app, Command, SuccessResult
13
+ from mcp_proxy_adapter.commands.command_registry import registry
14
+ from mcp_proxy_adapter.core.logging import logger
11
15
  from mcp_proxy_adapter.config import config
12
- from mcp_proxy_adapter.core.logging import logger, setup_logging
13
16
 
14
17
 
15
- def main():
18
+ class HelloCommand(Command):
19
+ """Простая команда, возвращающая приветствие."""
20
+
21
+ name = "hello"
22
+
23
+ async def execute(self, name: str = "World") -> SuccessResult:
24
+ """Выполняет команду с переданным именем."""
25
+ logger.info(f"Executing hello command with name: {name}")
26
+ return SuccessResult({"message": f"Hello, {name}!"})
27
+
28
+
29
+ def ensure_config():
30
+ """Проверяет наличие конфигурационного файла и создает его при необходимости."""
31
+ config_path = Path("config.json")
32
+
33
+ if not config_path.exists():
34
+ config_data = {
35
+ "server": {
36
+ "host": "0.0.0.0",
37
+ "port": 8000,
38
+ "debug": True,
39
+ "log_level": "INFO"
40
+ },
41
+ "logging": {
42
+ "level": "info",
43
+ "file": "logs/minimal_example.log",
44
+ "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
45
+ },
46
+ "debug": True
47
+ }
48
+
49
+ # Создаем директорию для логов
50
+ logs_dir = Path("logs")
51
+ logs_dir.mkdir(exist_ok=True)
52
+
53
+ # Записываем конфигурацию
54
+ with open(config_path, "w") as f:
55
+ json.dump(config_data, f, indent=2)
56
+
57
+ logger.info(f"Created default configuration at {config_path}")
58
+
59
+
60
+ def setup_application():
16
61
  """
17
- Main function to run the application.
62
+ Настраивает и возвращает FastAPI приложение.
18
63
  """
19
- # Убедимся что логирование настроено
20
- logger.info("Initializing logging configuration")
64
+ # Проверяем наличие конфигурационного файла
65
+ ensure_config()
66
+
67
+ # Определяем путь к конфигурационному файлу
68
+ config_path = Path("config.json").absolute()
69
+
70
+ # Загружаем конфигурацию из файла
71
+ if config_path.exists():
72
+ config.load_from_file(str(config_path))
73
+ logger.info(f"Loaded configuration from {config_path}")
21
74
 
75
+ # Создаем приложение
76
+ app = create_app()
77
+
78
+ # Корректно регистрируем команду
22
79
  try:
23
- # Получаем настройки логирования
24
- log_level = config.get("logging.level", "INFO")
25
- log_file = config.get("logging.file")
26
- rotation_type = config.get("logging.rotation.type", "size")
80
+ # Проверяем, есть ли уже команда в реестре
81
+ if registry.command_exists(HelloCommand.name):
82
+ # Если команда существует, удаляем ее
83
+ logger.info(f"Command '{HelloCommand.name}' already exists, re-registering it")
84
+ registry.unregister(HelloCommand.name)
27
85
 
28
- # Выводим информацию о настройках логирования
29
- logger.info(f"Log level: {log_level}")
30
- if log_file:
31
- logger.info(f"Log file: {log_file}")
32
- logger.info(f"Log rotation type: {rotation_type}")
33
-
34
- if rotation_type.lower() == "time":
35
- when = config.get("logging.rotation.when", "D")
36
- interval = config.get("logging.rotation.interval", 1)
37
- logger.info(f"Log rotation: every {interval} {when}")
38
- else:
39
- max_bytes = config.get("logging.rotation.max_bytes", 10 * 1024 * 1024)
40
- logger.info(f"Log rotation: when size reaches {max_bytes / (1024*1024):.1f} MB")
41
-
42
- backup_count = config.get("logging.rotation.backup_count", 5)
43
- logger.info(f"Log backups: {backup_count}")
44
- else:
45
- logger.info("File logging is disabled")
46
-
47
- # Get server settings
86
+ # Регистрируем команду
87
+ registry.register(HelloCommand)
88
+ logger.info(f"Command '{HelloCommand.name}' successfully registered")
89
+
90
+ # Выводим список всех зарегистрированных команд
91
+ commands = registry.get_all_commands()
92
+ logger.info(f"Total registered commands: {len(commands)}")
93
+ except Exception as e:
94
+ logger.error(f"Error registering command: {e}")
95
+
96
+ return app
97
+
98
+
99
+ def main():
100
+ """
101
+ Основная функция для запуска приложения.
102
+ """
103
+ try:
104
+ # Настраиваем приложение
105
+ app = setup_application()
106
+
107
+ # Получаем настройки сервера из конфигурации
48
108
  host = config.get("server.host", "0.0.0.0")
49
109
  port = config.get("server.port", 8000)
110
+ debug = config.get("server.debug", False)
50
111
 
51
- logger.info(f"Starting server on {host}:{port}")
112
+ logger.info(f"Starting server on {host}:{port} (debug: {debug})")
52
113
 
53
- # Run server
54
- uvicorn.run(
55
- app,
56
- host=host,
57
- port=port,
58
- reload=True if os.environ.get("DEBUG") else False,
59
- log_level=log_level.lower()
60
- )
114
+ if debug:
115
+ # В режиме отладки запускаем с перезагрузкой, используя строку импорта
116
+ uvicorn.run(
117
+ "main:setup_application",
118
+ host=host,
119
+ port=port,
120
+ reload=True,
121
+ factory=True
122
+ )
123
+ else:
124
+ # В обычном режиме запускаем экземпляр приложения
125
+ uvicorn.run(
126
+ app,
127
+ host=host,
128
+ port=port
129
+ )
61
130
  except Exception as e:
62
131
  logger.exception(f"Error during application startup: {e}")
63
132
  sys.exit(1)
@@ -1,15 +1,17 @@
1
1
  """
2
- Минимальный пример использования MCP Microservice.
2
+ Минимальный пример использования MCP Proxy Adapter.
3
3
 
4
4
  Этот пример демонстрирует минимальную конфигурацию для запуска микросервиса
5
5
  с одной простой командой.
6
6
  """
7
7
 
8
8
  import os
9
- from typing import Dict, Any
9
+ import uvicorn
10
+ from typing import Dict, Any, List
10
11
 
11
- import mcp_proxy_adapter as mcp
12
- from mcp_proxy_adapter import Command, SuccessResult
12
+ from mcp_proxy_adapter import Command, SuccessResult, create_app, registry
13
+ from mcp_proxy_adapter.core.logging import setup_logging
14
+ from mcp_proxy_adapter.config import config
13
15
 
14
16
 
15
17
  class HelloResult(SuccessResult):
@@ -97,27 +99,64 @@ class HelloCommand(Command):
97
99
  },
98
100
  "additionalProperties": False
99
101
  }
102
+
103
+ @classmethod
104
+ def _generate_examples(cls, params: Dict[str, Dict[str, Any]]) -> List[Dict[str, Any]]:
105
+ """
106
+ Генерирует примеры использования команды.
107
+
108
+ Args:
109
+ params: Информация о параметрах команды
110
+
111
+ Returns:
112
+ Список примеров
113
+ """
114
+ return [
115
+ {
116
+ "command": "hello",
117
+ "description": "Приветствие по умолчанию"
118
+ },
119
+ {
120
+ "command": "hello",
121
+ "params": {"name": "User"},
122
+ "description": "Приветствие с указанным именем"
123
+ }
124
+ ]
100
125
 
101
126
 
102
127
  def main():
103
128
  """Запуск микросервиса."""
104
129
  # Определяем путь к конфигурационному файлу
105
130
  current_dir = os.path.dirname(os.path.abspath(__file__))
106
- config_path = os.path.join(current_dir, "config.yaml")
131
+ config_path = os.path.join(current_dir, "config.json")
107
132
 
108
- # Создаем микросервис
109
- service = mcp.MicroService(
110
- title="Minimal Example",
111
- description="Минимальный пример использования MCP Microservice",
112
- version="1.0.0",
113
- config_path=config_path
114
- )
133
+ # Загружаем конфигурацию, если файл существует
134
+ if os.path.exists(config_path):
135
+ config.load_from_file(config_path)
136
+
137
+ # Настраиваем логирование
138
+ setup_logging("INFO")
139
+
140
+ # Создаем приложение FastAPI
141
+ app = create_app()
142
+ app.title = "Minimal Example"
143
+ app.description = "Минимальный пример использования MCP Proxy Adapter"
144
+ app.version = "1.0.0"
115
145
 
116
146
  # Регистрируем команду
117
- service.register_command(HelloCommand)
147
+ registry.register(HelloCommand)
148
+
149
+ # Определяем порт из переменной окружения или используем 8000 по умолчанию
150
+ port = int(os.environ.get("TEST_SERVER_PORT", 8000))
118
151
 
119
152
  # Запускаем сервер
120
- service.run(reload=True)
153
+ uvicorn.run(
154
+ app,
155
+ host="0.0.0.0",
156
+ port=port,
157
+ reload=False, # Отключаем автоперезагрузку для тестов
158
+ log_level="info"
159
+ )
121
160
 
122
161
 
123
162
  if __name__ == "__main__":
@@ -49,7 +49,7 @@ class ServerProcess:
49
49
  def start(self) -> None:
50
50
  """Start the server in a separate process."""
51
51
  def run_server():
52
- # Mock the configuration to use the test port
52
+ # Set the test port via environment variable
53
53
  os.environ["TEST_SERVER_PORT"] = str(self.port)
54
54
  simple_server.main()
55
55
 
@@ -1,5 +1,5 @@
1
1
  """
2
- Integration tests for the minimal example microservice.
2
+ Integration tests for the minimal example of MCP Proxy Adapter.
3
3
 
4
4
  These tests start a real server instance and test the API endpoints.
5
5
  """
@@ -145,9 +145,9 @@ class TestServerIntegration:
145
145
  assert "info" in schema
146
146
  assert "paths" in schema
147
147
 
148
- # Check hello command paths
149
- assert "/api/command/hello" in schema["paths"]
150
- assert "/api/jsonrpc" in schema["paths"]
148
+ # Проверяем наличие основных эндпоинтов
149
+ assert "/api/jsonrpc" in schema["paths"] or "/cmd" in schema["paths"]
150
+ assert "/api/commands" in schema["paths"]
151
151
 
152
152
  def test_docs_endpoint(self, server: ServerProcess, api_url: str):
153
153
  """Test the Swagger UI endpoint."""
@@ -170,14 +170,12 @@ class TestServerIntegration:
170
170
 
171
171
  # Check data structure
172
172
  assert "commands" in data
173
- assert isinstance(data["commands"], list)
173
+ assert isinstance(data["commands"], dict) # Теперь commands это словарь, а не список
174
174
 
175
175
  # Check if hello command is in the list
176
- hello_commands = [cmd for cmd in data["commands"] if cmd["name"] == "hello"]
177
- assert len(hello_commands) == 1
176
+ assert "hello" in data["commands"]
178
177
 
179
178
  # Check hello command details
180
- hello_cmd = hello_commands[0]
179
+ hello_cmd = data["commands"]["hello"]
181
180
  assert "name" in hello_cmd
182
- assert "description" in hello_cmd
183
- assert "parameters" in hello_cmd
181
+ assert hello_cmd["name"] == "hello"
examples/simple_server.py CHANGED
@@ -3,24 +3,21 @@
3
3
  Простой пример запуска сервера JSON-RPC с использованием MCP Proxy Adapter.
4
4
 
5
5
  Этот скрипт демонстрирует минимальную конфигурацию для запуска сервера JSON-RPC.
6
- Он создаёт экземпляр MicroService, регистрирует несколько команд и запускает сервер.
6
+ Он создаёт экземпляр приложения FastAPI с MCP Proxy Adapter и регистрирует пользовательские команды.
7
7
  """
8
8
 
9
9
  import os
10
10
  import argparse
11
11
  import sys
12
12
  from pathlib import Path
13
+ import uvicorn
13
14
 
14
15
  # Добавляем родительскую директорию в PYTHONPATH для импорта mcp_proxy_adapter
15
16
  sys.path.insert(0, str(Path(__file__).parent.parent))
16
17
 
17
- import mcp_proxy_adapter as mcp
18
- from mcp_proxy_adapter.framework import MicroService
19
- from examples.commands.echo_command import EchoCommand
20
- from examples.commands.get_date_command import GetDateCommand
21
- from examples.commands.new_uuid4_command import NewUuid4Command
18
+ from mcp_proxy_adapter import Command, SuccessResult, create_app
19
+ from mcp_proxy_adapter.commands.command_registry import registry
22
20
  from typing import Dict, Any, Optional
23
- from mcp_proxy_adapter import Command, SuccessResult
24
21
 
25
22
 
26
23
  class HelloResult(SuccessResult):
@@ -104,25 +101,19 @@ def main():
104
101
  parser.add_argument("--host", default="0.0.0.0", help="Host to bind server")
105
102
  parser.add_argument("--port", type=int, default=8000, help="Port to bind server")
106
103
  parser.add_argument("--reload", action="store_true", help="Enable auto-reload")
107
- parser.add_argument("--config", help="Path to config file")
108
104
 
109
105
  args = parser.parse_args()
110
106
 
111
- # Создаем экземпляр микросервиса
112
- service = MicroService(
113
- title="Simple Example Service",
114
- description="Example microservice demonstrating basic functionality",
115
- version="1.0.0",
116
- config_path=args.config
117
- )
107
+ # Регистрируем только свою пользовательскую команду
108
+ # встроенные команды и примеры регистрируются автоматически
109
+ registry.register(HelloCommand)
118
110
 
119
- # Регистрируем команды
120
- service.register_command(EchoCommand)
121
- service.register_command(GetDateCommand)
122
- service.register_command(NewUuid4Command)
111
+ # Создаем приложение FastAPI
112
+ app = create_app()
123
113
 
124
114
  # Запускаем сервер
125
- service.run(
115
+ uvicorn.run(
116
+ app,
126
117
  host=args.host,
127
118
  port=args.port,
128
119
  reload=args.reload
@@ -133,5 +124,5 @@ if __name__ == "__main__":
133
124
  # Run the simple server example
134
125
  # To test, open http://localhost:8000/docs in your browser
135
126
  # or use curl:
136
- # curl -X POST http://localhost:8000/api/jsonrpc -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"hello","params":{"name":"PyPI"},"id":1}'
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}'
137
128
  main()
examples/test_server.py CHANGED
@@ -7,15 +7,16 @@
7
7
  import os
8
8
  import argparse
9
9
  import sys
10
+ import uvicorn
10
11
  from pathlib import Path
11
12
  from typing import Dict, Any, Optional
12
13
 
13
14
  # Добавляем родительскую директорию в PYTHONPATH для импорта mcp_proxy_adapter
14
15
  sys.path.insert(0, str(Path(__file__).parent.parent))
15
16
 
16
- from mcp_proxy_adapter.framework import MicroService
17
- from mcp_proxy_adapter.commands.base import Command
18
- from mcp_proxy_adapter.commands.result import SuccessResult
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
19
20
 
20
21
 
21
22
  class HelloResult(SuccessResult):
@@ -96,29 +97,36 @@ def main():
96
97
  Основная функция для запуска сервера.
97
98
  """
98
99
  parser = argparse.ArgumentParser(description="Test JSON-RPC Microservice Server")
99
- parser.add_argument("--host", default="localhost", help="Host to bind server")
100
+ parser.add_argument("--host", default="0.0.0.0", help="Host to bind server")
100
101
  parser.add_argument("--port", type=int, default=8000, help="Port to bind server")
101
102
  parser.add_argument("--reload", action="store_true", help="Enable auto-reload")
102
103
  parser.add_argument("--config", help="Path to config file")
103
104
 
104
105
  args = parser.parse_args()
105
106
 
106
- # Создаем экземпляр микросервиса
107
- service = MicroService(
108
- title="Test Microservice",
109
- description="Test microservice for package installation verification",
110
- version="1.0.0",
111
- config_path=args.config
112
- )
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"
113
119
 
114
120
  # Регистрируем только одну команду для тестирования
115
- service.register_command(HelloCommand)
121
+ registry.register(HelloCommand)
116
122
 
117
123
  # Запускаем сервер
118
- service.run(
124
+ uvicorn.run(
125
+ app,
119
126
  host=args.host,
120
127
  port=args.port,
121
- reload=args.reload
128
+ reload=args.reload,
129
+ log_level="info"
122
130
  )
123
131
 
124
132
 
@@ -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())
File without changes