mcp-proxy-adapter 3.0.0__py3-none-any.whl → 3.0.2__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.
- examples/basic_example/README.md +123 -9
- examples/basic_example/config.json +4 -0
- examples/basic_example/docs/EN/README.md +46 -5
- examples/basic_example/docs/RU/README.md +46 -5
- examples/basic_example/server.py +127 -21
- examples/complete_example/commands/system_command.py +1 -0
- examples/complete_example/server.py +68 -40
- examples/minimal_example/README.md +20 -6
- examples/minimal_example/config.json +7 -14
- examples/minimal_example/main.py +109 -40
- examples/minimal_example/simple_server.py +53 -14
- examples/minimal_example/tests/conftest.py +1 -1
- examples/minimal_example/tests/test_integration.py +8 -10
- examples/simple_server.py +12 -21
- examples/test_server.py +22 -14
- examples/tool_description_example.py +82 -0
- mcp_proxy_adapter/api/__init__.py +0 -0
- mcp_proxy_adapter/api/app.py +391 -0
- mcp_proxy_adapter/api/handlers.py +229 -0
- mcp_proxy_adapter/api/middleware/__init__.py +49 -0
- mcp_proxy_adapter/api/middleware/auth.py +146 -0
- mcp_proxy_adapter/api/middleware/base.py +79 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +198 -0
- mcp_proxy_adapter/api/middleware/logging.py +96 -0
- mcp_proxy_adapter/api/middleware/performance.py +83 -0
- mcp_proxy_adapter/api/middleware/rate_limit.py +152 -0
- mcp_proxy_adapter/api/schemas.py +305 -0
- mcp_proxy_adapter/api/tool_integration.py +223 -0
- mcp_proxy_adapter/api/tools.py +198 -0
- mcp_proxy_adapter/commands/__init__.py +19 -0
- mcp_proxy_adapter/commands/base.py +301 -0
- mcp_proxy_adapter/commands/command_registry.py +231 -0
- mcp_proxy_adapter/commands/config_command.py +113 -0
- mcp_proxy_adapter/commands/health_command.py +136 -0
- mcp_proxy_adapter/commands/help_command.py +193 -0
- mcp_proxy_adapter/commands/result.py +215 -0
- mcp_proxy_adapter/config.py +9 -0
- mcp_proxy_adapter/core/__init__.py +0 -0
- mcp_proxy_adapter/core/errors.py +173 -0
- mcp_proxy_adapter/core/logging.py +205 -0
- mcp_proxy_adapter/core/utils.py +138 -0
- mcp_proxy_adapter/custom_openapi.py +47 -10
- mcp_proxy_adapter/py.typed +0 -0
- mcp_proxy_adapter/schemas/base_schema.json +114 -0
- mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
- mcp_proxy_adapter/tests/__init__.py +0 -0
- mcp_proxy_adapter/tests/api/__init__.py +3 -0
- mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +115 -0
- mcp_proxy_adapter/tests/api/test_middleware.py +336 -0
- mcp_proxy_adapter/tests/commands/__init__.py +3 -0
- mcp_proxy_adapter/tests/commands/test_config_command.py +211 -0
- mcp_proxy_adapter/tests/commands/test_echo_command.py +127 -0
- mcp_proxy_adapter/tests/commands/test_help_command.py +133 -0
- mcp_proxy_adapter/tests/conftest.py +131 -0
- mcp_proxy_adapter/tests/functional/__init__.py +3 -0
- mcp_proxy_adapter/tests/functional/test_api.py +253 -0
- mcp_proxy_adapter/tests/integration/__init__.py +3 -0
- mcp_proxy_adapter/tests/integration/test_cmd_integration.py +130 -0
- mcp_proxy_adapter/tests/integration/test_integration.py +255 -0
- mcp_proxy_adapter/tests/performance/__init__.py +3 -0
- mcp_proxy_adapter/tests/performance/test_performance.py +189 -0
- mcp_proxy_adapter/tests/stubs/__init__.py +10 -0
- mcp_proxy_adapter/tests/stubs/echo_command.py +104 -0
- mcp_proxy_adapter/tests/test_api_endpoints.py +271 -0
- mcp_proxy_adapter/tests/test_api_handlers.py +289 -0
- mcp_proxy_adapter/tests/test_base_command.py +123 -0
- mcp_proxy_adapter/tests/test_batch_requests.py +117 -0
- mcp_proxy_adapter/tests/test_command_registry.py +245 -0
- mcp_proxy_adapter/tests/test_config.py +127 -0
- mcp_proxy_adapter/tests/test_utils.py +65 -0
- mcp_proxy_adapter/tests/unit/__init__.py +3 -0
- mcp_proxy_adapter/tests/unit/test_base_command.py +130 -0
- mcp_proxy_adapter/tests/unit/test_config.py +217 -0
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.2.dist-info}/METADATA +1 -1
- mcp_proxy_adapter-3.0.2.dist-info/RECORD +109 -0
- examples/basic_example/config.yaml +0 -20
- examples/basic_example/main.py +0 -50
- examples/complete_example/main.py +0 -67
- examples/minimal_example/config.yaml +0 -26
- mcp_proxy_adapter/framework.py +0 -109
- mcp_proxy_adapter-3.0.0.dist-info/RECORD +0 -58
- {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.2.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.2.dist-info}/licenses/LICENSE +0 -0
- {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.2.dist-info}/top_level.txt +0 -0
examples/basic_example/README.md
CHANGED
@@ -1,7 +1,120 @@
|
|
1
|
-
#
|
1
|
+
# Basic MCP Proxy Adapter Example
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
This example demonstrates how to use MCP Proxy Adapter to create a microservice with multiple commands organized in separate files.
|
4
|
+
|
5
|
+
## English Documentation
|
6
|
+
|
7
|
+
### Overview
|
8
|
+
|
9
|
+
This example shows:
|
10
|
+
- Creating a microservice using MCP Proxy Adapter
|
11
|
+
- Configuring the service using JSON configuration file
|
12
|
+
- Automatic command discovery from a package
|
13
|
+
- Implementing various command types with their result classes
|
14
|
+
- Running the service with auto-reload for development
|
15
|
+
|
16
|
+
### Setup
|
17
|
+
|
18
|
+
1. Make sure you have installed MCP Proxy Adapter package
|
19
|
+
2. Install additional dependencies:
|
20
|
+
```
|
21
|
+
pip install pytz uvicorn
|
22
|
+
```
|
23
|
+
|
24
|
+
### Configuration
|
25
|
+
|
26
|
+
The service uses `config.json` for configuration. The key settings are:
|
27
|
+
- Server host and port
|
28
|
+
- Logging configuration
|
29
|
+
- Command discovery settings
|
30
|
+
|
31
|
+
### Available Commands
|
32
|
+
|
33
|
+
The example includes several commands:
|
34
|
+
- `echo` - Echo back a message
|
35
|
+
- `time` - Get current time in different formats and timezones
|
36
|
+
- `math` - Perform basic math operations
|
37
|
+
|
38
|
+
### Running the Example
|
39
|
+
|
40
|
+
```bash
|
41
|
+
cd examples/basic_example
|
42
|
+
python server.py
|
43
|
+
```
|
44
|
+
|
45
|
+
The service will start on http://localhost:8000 by default, with API documentation available at http://localhost:8000/docs
|
46
|
+
|
47
|
+
### Testing Commands
|
48
|
+
|
49
|
+
You can test commands using curl:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
# Echo command
|
53
|
+
curl -X POST http://localhost:8000/cmd -H "Content-Type: application/json" -d '{"command": "echo", "params": {"message": "Hello, world!"}}'
|
54
|
+
|
55
|
+
# Time command
|
56
|
+
curl -X POST http://localhost:8000/cmd -H "Content-Type: application/json" -d '{"command": "time", "params": {"timezone": "Europe/London"}}'
|
57
|
+
|
58
|
+
# JSON-RPC style request
|
59
|
+
curl -X POST http://localhost:8000/api/jsonrpc -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "echo", "params": {"message": "Hello RPC!"}, "id": 1}'
|
60
|
+
```
|
61
|
+
|
62
|
+
## Русская документация
|
63
|
+
|
64
|
+
### Обзор
|
65
|
+
|
66
|
+
Этот пример демонстрирует:
|
67
|
+
- Создание микросервиса с использованием MCP Proxy Adapter
|
68
|
+
- Настройку сервиса с использованием JSON-файла конфигурации
|
69
|
+
- Автоматическое обнаружение команд из пакета
|
70
|
+
- Реализацию различных типов команд с их классами результатов
|
71
|
+
- Запуск сервиса с автоперезагрузкой для разработки
|
72
|
+
|
73
|
+
### Настройка
|
74
|
+
|
75
|
+
1. Убедитесь, что у вас установлен пакет MCP Proxy Adapter
|
76
|
+
2. Установите дополнительные зависимости:
|
77
|
+
```
|
78
|
+
pip install pytz uvicorn
|
79
|
+
```
|
80
|
+
|
81
|
+
### Конфигурация
|
82
|
+
|
83
|
+
Сервис использует `config.json` для конфигурации. Основные настройки:
|
84
|
+
- Хост и порт сервера
|
85
|
+
- Настройки логирования
|
86
|
+
- Настройки обнаружения команд
|
87
|
+
|
88
|
+
### Доступные команды
|
89
|
+
|
90
|
+
Пример включает несколько команд:
|
91
|
+
- `echo` - Эхо-ответ сообщения
|
92
|
+
- `time` - Получение текущего времени в разных форматах и часовых поясах
|
93
|
+
- `math` - Выполнение базовых математических операций
|
94
|
+
|
95
|
+
### Запуск примера
|
96
|
+
|
97
|
+
```bash
|
98
|
+
cd examples/basic_example
|
99
|
+
python server.py
|
100
|
+
```
|
101
|
+
|
102
|
+
Сервис запустится на http://localhost:8000 по умолчанию, документация API доступна по адресу http://localhost:8000/docs
|
103
|
+
|
104
|
+
### Тестирование команд
|
105
|
+
|
106
|
+
Вы можете тестировать команды с помощью curl:
|
107
|
+
|
108
|
+
```bash
|
109
|
+
# Команда echo
|
110
|
+
curl -X POST http://localhost:8000/cmd -H "Content-Type: application/json" -d '{"command": "echo", "params": {"message": "Привет, мир!"}}'
|
111
|
+
|
112
|
+
# Команда time
|
113
|
+
curl -X POST http://localhost:8000/cmd -H "Content-Type: application/json" -d '{"command": "time", "params": {"timezone": "Europe/Moscow"}}'
|
114
|
+
|
115
|
+
# Запрос в стиле JSON-RPC
|
116
|
+
curl -X POST http://localhost:8000/api/jsonrpc -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "echo", "params": {"message": "Привет RPC!"}, "id": 1}'
|
117
|
+
```
|
5
118
|
|
6
119
|
## Структура примера
|
7
120
|
|
@@ -12,7 +125,7 @@ basic_example/
|
|
12
125
|
│ ├── echo_command.py # Команда эхо
|
13
126
|
│ ├── math_command.py # Математическая команда
|
14
127
|
│ └── time_command.py # Команда времени
|
15
|
-
├── config.
|
128
|
+
├── config.json # Файл конфигурации JSON
|
16
129
|
├── README.md # Документация
|
17
130
|
└── server.py # Файл запуска сервера
|
18
131
|
```
|
@@ -124,8 +237,9 @@ curl -X POST "http://localhost:8000/api/command/time" \
|
|
124
237
|
|
125
238
|
## Что демонстрирует этот пример
|
126
239
|
|
127
|
-
1.
|
128
|
-
2.
|
129
|
-
3.
|
130
|
-
4.
|
131
|
-
5.
|
240
|
+
1. Прямое использование FastAPI и uvicorn с MCP Proxy Adapter
|
241
|
+
2. Организация команд в отдельные файлы
|
242
|
+
3. Автоматическое обнаружение и регистрация команд
|
243
|
+
4. Различные типы команд и параметров
|
244
|
+
5. Обработка ошибок
|
245
|
+
6. Различные способы вызова команд (JSON-RPC, /cmd, /api/command/{command_name})
|
@@ -12,14 +12,16 @@ basic_example/
|
|
12
12
|
│ ├── echo_command.py # Echo command
|
13
13
|
│ ├── math_command.py # Math command
|
14
14
|
│ └── time_command.py # Time command
|
15
|
-
├── config.
|
15
|
+
├── config.json # JSON configuration file
|
16
16
|
├── docs/ # Documentation
|
17
17
|
│ ├── EN/ # English documentation
|
18
18
|
│ │ └── README.md # This file
|
19
19
|
│ └── RU/ # Russian documentation
|
20
20
|
│ └── README.md # Russian version of this file
|
21
21
|
├── logs/ # Logs directory
|
22
|
-
|
22
|
+
├── server.py # Server startup and application logic
|
23
|
+
└── tests/ # Tests directory
|
24
|
+
└── conftest.py # Test configuration and fixtures
|
23
25
|
```
|
24
26
|
|
25
27
|
## Running the Example
|
@@ -31,12 +33,48 @@ cd examples/basic_example
|
|
31
33
|
# Create logs directory if it doesn't exist
|
32
34
|
mkdir -p logs
|
33
35
|
|
34
|
-
# Run the server
|
36
|
+
# Run the server with default configuration (config.json)
|
35
37
|
python server.py
|
38
|
+
|
39
|
+
# Or run with a specific configuration file
|
40
|
+
python server.py --config other_config.json
|
36
41
|
```
|
37
42
|
|
38
43
|
After starting, the server will be available at [http://localhost:8000](http://localhost:8000).
|
39
44
|
|
45
|
+
## Configuration
|
46
|
+
|
47
|
+
The server reads configuration from JSON files. By default, it uses `config.json` in the same directory as `server.py`.
|
48
|
+
|
49
|
+
You can specify a different configuration file with the `--config` parameter:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
python server.py --config my_custom_config.json
|
53
|
+
```
|
54
|
+
|
55
|
+
If the specified configuration file doesn't exist, the server will try to fall back to `config.json`.
|
56
|
+
|
57
|
+
The main configuration options are:
|
58
|
+
|
59
|
+
```json
|
60
|
+
{
|
61
|
+
"server": {
|
62
|
+
"host": "0.0.0.0",
|
63
|
+
"port": 8000,
|
64
|
+
"debug": true,
|
65
|
+
"log_level": "info"
|
66
|
+
},
|
67
|
+
"logging": {
|
68
|
+
"level": "INFO",
|
69
|
+
"file": "logs/basic_example.log"
|
70
|
+
}
|
71
|
+
}
|
72
|
+
```
|
73
|
+
|
74
|
+
The server can run in two modes:
|
75
|
+
- Normal mode: Uses a pre-configured application instance
|
76
|
+
- Debug mode: Uses hot reload (when `"debug": true` in config)
|
77
|
+
|
40
78
|
## Available Commands
|
41
79
|
|
42
80
|
### 1. `echo` - Echo Command
|
@@ -132,5 +170,8 @@ curl -X POST "http://localhost:8000/api/command/time" \
|
|
132
170
|
1. Command organization in separate files
|
133
171
|
2. Automatic command discovery and registration
|
134
172
|
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})
|
173
|
+
4. Error handling and automatic command reregistration
|
174
|
+
5. Different ways to call commands (JSON-RPC, /cmd, /api/command/{command_name})
|
175
|
+
6. Support for debug mode with hot reload
|
176
|
+
7. Safe command registration for preventing conflicts
|
177
|
+
8. JSON configuration files with command-line options
|
@@ -12,14 +12,16 @@ basic_example/
|
|
12
12
|
│ ├── echo_command.py # Команда эхо
|
13
13
|
│ ├── math_command.py # Математическая команда
|
14
14
|
│ └── time_command.py # Команда времени
|
15
|
-
├── config.
|
15
|
+
├── config.json # Файл конфигурации JSON
|
16
16
|
├── docs/ # Документация
|
17
17
|
│ ├── EN/ # Английская документация
|
18
18
|
│ │ └── README.md # Английская версия данного файла
|
19
19
|
│ └── RU/ # Русская документация
|
20
20
|
│ └── README.md # Этот файл
|
21
21
|
├── logs/ # Директория для логов
|
22
|
-
|
22
|
+
├── server.py # Файл запуска сервера и логики приложения
|
23
|
+
└── tests/ # Директория с тестами
|
24
|
+
└── conftest.py # Конфигурация и фикстуры для тестов
|
23
25
|
```
|
24
26
|
|
25
27
|
## Запуск примера
|
@@ -31,12 +33,48 @@ cd examples/basic_example
|
|
31
33
|
# Создать директорию для логов, если она не существует
|
32
34
|
mkdir -p logs
|
33
35
|
|
34
|
-
# Запустить сервер
|
36
|
+
# Запустить сервер с конфигурацией по умолчанию (config.json)
|
35
37
|
python server.py
|
38
|
+
|
39
|
+
# Или запустить с указанием другого файла конфигурации
|
40
|
+
python server.py --config другой_конфиг.json
|
36
41
|
```
|
37
42
|
|
38
43
|
После запуска сервер будет доступен по адресу [http://localhost:8000](http://localhost:8000).
|
39
44
|
|
45
|
+
## Конфигурация
|
46
|
+
|
47
|
+
Сервер считывает конфигурацию из JSON-файлов. По умолчанию используется `config.json` в том же каталоге, где находится `server.py`.
|
48
|
+
|
49
|
+
Вы можете указать другой файл конфигурации с помощью параметра `--config`:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
python server.py --config мой_конфиг.json
|
53
|
+
```
|
54
|
+
|
55
|
+
Если указанный файл конфигурации не существует, сервер попытается использовать `config.json`.
|
56
|
+
|
57
|
+
Основные параметры конфигурации:
|
58
|
+
|
59
|
+
```json
|
60
|
+
{
|
61
|
+
"server": {
|
62
|
+
"host": "0.0.0.0",
|
63
|
+
"port": 8000,
|
64
|
+
"debug": true,
|
65
|
+
"log_level": "info"
|
66
|
+
},
|
67
|
+
"logging": {
|
68
|
+
"level": "INFO",
|
69
|
+
"file": "logs/basic_example.log"
|
70
|
+
}
|
71
|
+
}
|
72
|
+
```
|
73
|
+
|
74
|
+
Сервер может работать в двух режимах:
|
75
|
+
- Обычный режим: использует предварительно настроенный экземпляр приложения
|
76
|
+
- Режим отладки: использует горячую перезагрузку (когда `"debug": true` в конфигурации)
|
77
|
+
|
40
78
|
## Доступные команды
|
41
79
|
|
42
80
|
### 1. `echo` - Эхо-команда
|
@@ -132,5 +170,8 @@ curl -X POST "http://localhost:8000/api/command/time" \
|
|
132
170
|
1. Организация команд в отдельные файлы
|
133
171
|
2. Автоматическое обнаружение и регистрация команд
|
134
172
|
3. Различные типы команд и параметров
|
135
|
-
4. Обработка ошибок
|
136
|
-
5. Различные способы вызова команд (JSON-RPC, /cmd, /api/command/{command_name})
|
173
|
+
4. Обработка ошибок и автоматическая перерегистрация команд
|
174
|
+
5. Различные способы вызова команд (JSON-RPC, /cmd, /api/command/{command_name})
|
175
|
+
6. Поддержка режима отладки с горячей перезагрузкой
|
176
|
+
7. Безопасная регистрация команд для предотвращения конфликтов
|
177
|
+
8. JSON-файлы конфигурации с опциями командной строки
|
examples/basic_example/server.py
CHANGED
@@ -1,44 +1,150 @@
|
|
1
1
|
"""
|
2
|
-
Basic MCP
|
2
|
+
Basic MCP Proxy Adapter example.
|
3
3
|
|
4
|
-
This example demonstrates
|
5
|
-
organized in separate files.
|
4
|
+
This example demonstrates how to use MCP Proxy Adapter to create
|
5
|
+
a microservice with multiple commands organized in separate files.
|
6
6
|
"""
|
7
7
|
|
8
8
|
import os
|
9
9
|
import sys
|
10
|
+
import json
|
11
|
+
import argparse
|
12
|
+
import uvicorn
|
10
13
|
from typing import Dict, Any
|
14
|
+
from pathlib import Path
|
11
15
|
|
12
|
-
|
13
|
-
from mcp_proxy_adapter import
|
16
|
+
from mcp_proxy_adapter import Command, CommandResult, registry
|
17
|
+
from mcp_proxy_adapter.api.app import create_app
|
18
|
+
from mcp_proxy_adapter.config import config
|
19
|
+
from mcp_proxy_adapter.core.logging import logger, setup_logging
|
14
20
|
|
15
21
|
# Add commands directory to path for local imports
|
16
22
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
17
23
|
|
18
24
|
|
19
|
-
def
|
20
|
-
"""
|
25
|
+
def parse_args():
|
26
|
+
"""
|
27
|
+
Parse command line arguments.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
Parsed arguments
|
31
|
+
"""
|
32
|
+
parser = argparse.ArgumentParser(description="Basic MCP Microservice Example")
|
33
|
+
parser.add_argument(
|
34
|
+
"--config",
|
35
|
+
default="config.json",
|
36
|
+
help="Path to configuration file (default: config.json)"
|
37
|
+
)
|
38
|
+
return parser.parse_args()
|
39
|
+
|
40
|
+
|
41
|
+
def setup_application(config_file=None):
|
42
|
+
"""
|
43
|
+
Настраивает и возвращает FastAPI приложение.
|
44
|
+
"""
|
45
|
+
# Get config file path
|
46
|
+
if config_file is None:
|
47
|
+
args = parse_args()
|
48
|
+
config_file = args.config
|
49
|
+
|
21
50
|
# Get absolute paths
|
22
|
-
current_dir =
|
23
|
-
config_path =
|
51
|
+
current_dir = Path(__file__).parent.absolute()
|
52
|
+
config_path = current_dir / config_file
|
53
|
+
|
54
|
+
# Try alternative config file if specified one doesn't exist
|
55
|
+
if not config_path.exists() and config_file != "config.json":
|
56
|
+
fallback_path = current_dir / "config.json"
|
57
|
+
if fallback_path.exists():
|
58
|
+
logger.warning(f"Config file {config_path} not found, using {fallback_path} instead")
|
59
|
+
config_path = fallback_path
|
24
60
|
|
25
61
|
# Create log directory if it doesn't exist
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
62
|
+
logs_dir = current_dir / "logs"
|
63
|
+
logs_dir.mkdir(exist_ok=True)
|
64
|
+
|
65
|
+
# Load configuration if config file exists
|
66
|
+
if config_path.exists():
|
67
|
+
# Make sure we're only loading JSON files
|
68
|
+
if not str(config_path).lower().endswith('.json'):
|
69
|
+
logger.warning(f"Config file {config_path} is not a JSON file, only JSON format is supported")
|
70
|
+
config_path = current_dir / "config.json"
|
71
|
+
if not config_path.exists():
|
72
|
+
logger.warning(f"Default config.json not found, using default values")
|
73
|
+
|
74
|
+
if config_path.exists():
|
75
|
+
config.load_from_file(str(config_path))
|
76
|
+
logger.info(f"Loaded configuration from {config_path}")
|
77
|
+
else:
|
78
|
+
logger.warning(f"Configuration file {config_path} not found, using defaults")
|
79
|
+
|
80
|
+
# Create FastAPI app
|
81
|
+
app = create_app()
|
82
|
+
app.title = "Basic MCP Proxy Adapter Example"
|
83
|
+
app.description = "Example microservice with multiple commands using MCP Proxy Adapter"
|
84
|
+
app.version = "1.0.0"
|
35
85
|
|
36
86
|
# Discover and register commands from the commands directory
|
37
|
-
package_path = "commands"
|
38
|
-
|
87
|
+
package_path = "commands"
|
88
|
+
try:
|
89
|
+
# Clear existing commands to prevent conflicts in test environment
|
90
|
+
registered_commands = registry.get_all_commands()
|
91
|
+
for cmd_name in list(registered_commands.keys()):
|
92
|
+
try:
|
93
|
+
registry.unregister(cmd_name)
|
94
|
+
except Exception as e:
|
95
|
+
logger.debug(f"Error unregistering command {cmd_name}: {e}")
|
96
|
+
|
97
|
+
# Discover and register commands
|
98
|
+
registry.discover_commands(package_path)
|
99
|
+
logger.info(f"Discovered commands from package: {package_path}")
|
100
|
+
except Exception as e:
|
101
|
+
logger.error(f"Error discovering commands: {e}")
|
102
|
+
|
103
|
+
return app
|
104
|
+
|
105
|
+
|
106
|
+
def main():
|
107
|
+
"""Run microservice with command discovery."""
|
108
|
+
# Setup logging
|
109
|
+
log_level = config.get("logging.level", "INFO")
|
110
|
+
setup_logging(log_level)
|
111
|
+
|
112
|
+
# Initialize application
|
113
|
+
app = setup_application()
|
114
|
+
|
115
|
+
# Get server configuration
|
116
|
+
host = config.get("server.host", "localhost")
|
117
|
+
port = config.get("server.port", 8000)
|
118
|
+
|
119
|
+
# Check if port is overridden by environment variable (for testing)
|
120
|
+
if "TEST_SERVER_PORT" in os.environ:
|
121
|
+
port = int(os.environ["TEST_SERVER_PORT"])
|
122
|
+
logger.info(f"Using test port from environment: {port}")
|
39
123
|
|
40
124
|
# Run server
|
41
|
-
|
125
|
+
logger.info(f"Starting server on {host}:{port}")
|
126
|
+
|
127
|
+
debug = config.get("server.debug", False)
|
128
|
+
|
129
|
+
if debug:
|
130
|
+
# In debug mode, run with hot reload using import string
|
131
|
+
uvicorn.run(
|
132
|
+
"server:setup_application",
|
133
|
+
host=host,
|
134
|
+
port=port,
|
135
|
+
reload=True,
|
136
|
+
factory=True,
|
137
|
+
log_level=config.get("logging.level", "info").lower()
|
138
|
+
)
|
139
|
+
else:
|
140
|
+
# In normal mode, run with app instance
|
141
|
+
uvicorn.run(
|
142
|
+
app,
|
143
|
+
host=host,
|
144
|
+
port=port,
|
145
|
+
reload=False,
|
146
|
+
log_level=config.get("logging.level", "info").lower()
|
147
|
+
)
|
42
148
|
|
43
149
|
|
44
150
|
if __name__ == "__main__":
|
@@ -8,10 +8,12 @@ environment-specific configuration, and multiple commands.
|
|
8
8
|
import os
|
9
9
|
import sys
|
10
10
|
import argparse
|
11
|
-
from
|
12
|
-
|
13
|
-
|
14
|
-
from mcp_proxy_adapter import
|
11
|
+
from pathlib import Path
|
12
|
+
import uvicorn
|
13
|
+
from mcp_proxy_adapter.api.app import create_app
|
14
|
+
from mcp_proxy_adapter.commands.command_registry import registry
|
15
|
+
from mcp_proxy_adapter.config import config
|
16
|
+
from mcp_proxy_adapter.core.logging import logger, setup_logging
|
15
17
|
|
16
18
|
# Add commands directory to path for local imports
|
17
19
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
@@ -24,61 +26,87 @@ def parse_args():
|
|
24
26
|
Returns:
|
25
27
|
Parsed arguments
|
26
28
|
"""
|
27
|
-
parser = argparse.ArgumentParser(description="MCP
|
29
|
+
parser = argparse.ArgumentParser(description="MCP Complete Example")
|
28
30
|
parser.add_argument(
|
29
|
-
"--config",
|
31
|
+
"--config",
|
30
32
|
default="configs/config.dev.yaml",
|
31
33
|
help="Path to configuration file"
|
32
34
|
)
|
33
35
|
return parser.parse_args()
|
34
36
|
|
35
37
|
|
36
|
-
def ensure_directories(
|
38
|
+
def ensure_directories():
|
37
39
|
"""
|
38
40
|
Create necessary directories based on configuration.
|
39
|
-
|
40
|
-
Args:
|
41
|
-
config_path: Path to configuration file
|
42
41
|
"""
|
43
|
-
# Extract base directory
|
44
42
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
45
|
-
|
46
|
-
# Create logs directory
|
47
43
|
os.makedirs(os.path.join(base_dir, "logs"), exist_ok=True)
|
48
|
-
|
49
|
-
# Create cache directory
|
50
44
|
os.makedirs(os.path.join(base_dir, "cache"), exist_ok=True)
|
51
|
-
|
52
|
-
# Create data directory
|
53
45
|
os.makedirs(os.path.join(base_dir, "data"), exist_ok=True)
|
54
46
|
|
55
47
|
|
48
|
+
def setup_application(config_file=None):
|
49
|
+
"""
|
50
|
+
Setup and configure the microservice application.
|
51
|
+
|
52
|
+
Args:
|
53
|
+
config_file: Path to configuration file (optional)
|
54
|
+
|
55
|
+
Returns:
|
56
|
+
Configured FastAPI application
|
57
|
+
"""
|
58
|
+
if config_file is None:
|
59
|
+
args = parse_args()
|
60
|
+
config_file = args.config
|
61
|
+
current_dir = Path(__file__).parent.absolute()
|
62
|
+
config_path = current_dir / config_file
|
63
|
+
if not config_path.exists():
|
64
|
+
config_path = current_dir / "config.json"
|
65
|
+
ensure_directories()
|
66
|
+
if config_path.exists():
|
67
|
+
config.load_from_file(str(config_path))
|
68
|
+
logger.info(f"Loaded configuration from {config_path}")
|
69
|
+
else:
|
70
|
+
logger.warning(f"Configuration file {config_path} not found, using defaults")
|
71
|
+
app = create_app()
|
72
|
+
app.title = "Complete MCP Microservice Example"
|
73
|
+
app.description = "Full-featured microservice with Docker support"
|
74
|
+
app.version = "1.0.0"
|
75
|
+
# Discover and register commands from the commands directory
|
76
|
+
package_path = "commands"
|
77
|
+
try:
|
78
|
+
registered_commands = registry.get_all_commands()
|
79
|
+
for cmd_name in list(registered_commands.keys()):
|
80
|
+
try:
|
81
|
+
registry.unregister(cmd_name)
|
82
|
+
except Exception as e:
|
83
|
+
logger.debug(f"Error unregistering command {cmd_name}: {e}")
|
84
|
+
registry.discover_commands(package_path)
|
85
|
+
logger.info(f"Discovered commands from package: {package_path}")
|
86
|
+
except Exception as e:
|
87
|
+
logger.error(f"Error discovering commands: {e}")
|
88
|
+
return app
|
89
|
+
|
90
|
+
|
56
91
|
def main():
|
57
92
|
"""Run microservice with command discovery."""
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
93
|
+
log_level = config.get("logging.level", "INFO")
|
94
|
+
setup_logging(log_level)
|
95
|
+
app = setup_application()
|
96
|
+
host = config.get("server.host", "0.0.0.0")
|
97
|
+
port = config.get("server.port", 8000)
|
98
|
+
if "TEST_SERVER_PORT" in os.environ:
|
99
|
+
port = int(os.environ["TEST_SERVER_PORT"])
|
100
|
+
logger.info(f"Using test port from environment: {port}")
|
101
|
+
logger.info(f"Starting server on {host}:{port}")
|
102
|
+
debug = config.get("server.debug", False)
|
103
|
+
uvicorn.run(
|
104
|
+
app,
|
105
|
+
host=host,
|
106
|
+
port=port,
|
107
|
+
reload=debug,
|
108
|
+
log_level=log_level.lower()
|
74
109
|
)
|
75
|
-
|
76
|
-
# Discover and register commands
|
77
|
-
package_path = "commands"
|
78
|
-
service.discover_commands(package_path)
|
79
|
-
|
80
|
-
# Run server with parameters from configuration
|
81
|
-
service.run()
|
82
110
|
|
83
111
|
|
84
112
|
if __name__ == "__main__":
|