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.
- examples/__init__.py +19 -0
- examples/anti_patterns/README.md +51 -0
- examples/anti_patterns/__init__.py +9 -0
- examples/anti_patterns/bad_design/README.md +72 -0
- examples/anti_patterns/bad_design/global_state.py +170 -0
- examples/anti_patterns/bad_design/monolithic_command.py +272 -0
- examples/basic_example/README.md +245 -0
- examples/basic_example/__init__.py +8 -0
- examples/basic_example/commands/__init__.py +5 -0
- examples/basic_example/commands/echo_command.py +95 -0
- examples/basic_example/commands/math_command.py +151 -0
- examples/basic_example/commands/time_command.py +152 -0
- examples/basic_example/config.json +25 -0
- examples/basic_example/docs/EN/README.md +177 -0
- examples/basic_example/docs/RU/README.md +177 -0
- examples/basic_example/server.py +151 -0
- examples/basic_example/tests/conftest.py +243 -0
- examples/commands/echo_command.py +52 -0
- examples/commands/echo_result.py +65 -0
- examples/commands/get_date_command.py +98 -0
- examples/commands/new_uuid4_command.py +91 -0
- examples/complete_example/Dockerfile +24 -0
- examples/complete_example/README.md +92 -0
- examples/complete_example/__init__.py +8 -0
- examples/complete_example/commands/__init__.py +5 -0
- examples/complete_example/commands/system_command.py +328 -0
- examples/complete_example/config.json +41 -0
- examples/complete_example/configs/config.dev.yaml +40 -0
- examples/complete_example/configs/config.docker.yaml +40 -0
- examples/complete_example/docker-compose.yml +35 -0
- examples/complete_example/requirements.txt +20 -0
- examples/complete_example/server.py +139 -0
- examples/minimal_example/README.md +65 -0
- examples/minimal_example/__init__.py +8 -0
- examples/minimal_example/config.json +14 -0
- examples/minimal_example/main.py +136 -0
- examples/minimal_example/simple_server.py +163 -0
- examples/minimal_example/tests/conftest.py +171 -0
- examples/minimal_example/tests/test_hello_command.py +111 -0
- examples/minimal_example/tests/test_integration.py +181 -0
- examples/server.py +69 -0
- examples/simple_server.py +128 -0
- examples/test_server.py +134 -0
- examples/tool_description_example.py +82 -0
- mcp_proxy_adapter/__init__.py +33 -1
- 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 +195 -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 +125 -0
- mcp_proxy_adapter/openapi.py +403 -0
- 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 +235 -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 +3 -0
- mcp_proxy_adapter-3.0.1.dist-info/METADATA +200 -0
- mcp_proxy_adapter-3.0.1.dist-info/RECORD +109 -0
- {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/top_level.txt +1 -0
- mcp_proxy_adapter/adapter.py +0 -697
- mcp_proxy_adapter/analyzers/__init__.py +0 -1
- mcp_proxy_adapter/analyzers/docstring_analyzer.py +0 -199
- mcp_proxy_adapter/analyzers/type_analyzer.py +0 -151
- mcp_proxy_adapter/dispatchers/__init__.py +0 -1
- mcp_proxy_adapter/dispatchers/base_dispatcher.py +0 -85
- mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py +0 -262
- mcp_proxy_adapter/examples/analyze_config.py +0 -141
- mcp_proxy_adapter/examples/basic_integration.py +0 -155
- mcp_proxy_adapter/examples/docstring_and_schema_example.py +0 -69
- mcp_proxy_adapter/examples/extension_example.py +0 -72
- mcp_proxy_adapter/examples/help_best_practices.py +0 -67
- mcp_proxy_adapter/examples/help_usage.py +0 -64
- mcp_proxy_adapter/examples/mcp_proxy_client.py +0 -131
- mcp_proxy_adapter/examples/openapi_server.py +0 -383
- mcp_proxy_adapter/examples/project_structure_example.py +0 -47
- mcp_proxy_adapter/examples/testing_example.py +0 -64
- mcp_proxy_adapter/models.py +0 -47
- mcp_proxy_adapter/registry.py +0 -439
- mcp_proxy_adapter/schema.py +0 -257
- mcp_proxy_adapter/testing_utils.py +0 -112
- mcp_proxy_adapter/validators/__init__.py +0 -1
- mcp_proxy_adapter/validators/docstring_validator.py +0 -75
- mcp_proxy_adapter/validators/metadata_validator.py +0 -76
- mcp_proxy_adapter-2.1.17.dist-info/METADATA +0 -376
- mcp_proxy_adapter-2.1.17.dist-info/RECORD +0 -30
- {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,177 @@
|
|
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.json # JSON 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 and application logic
|
23
|
+
└── tests/ # Tests directory
|
24
|
+
└── conftest.py # Test configuration and fixtures
|
25
|
+
```
|
26
|
+
|
27
|
+
## Running the Example
|
28
|
+
|
29
|
+
```bash
|
30
|
+
# Navigate to the project directory
|
31
|
+
cd examples/basic_example
|
32
|
+
|
33
|
+
# Create logs directory if it doesn't exist
|
34
|
+
mkdir -p logs
|
35
|
+
|
36
|
+
# Run the server with default configuration (config.json)
|
37
|
+
python server.py
|
38
|
+
|
39
|
+
# Or run with a specific configuration file
|
40
|
+
python server.py --config other_config.json
|
41
|
+
```
|
42
|
+
|
43
|
+
After starting, the server will be available at [http://localhost:8000](http://localhost:8000).
|
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
|
+
|
78
|
+
## Available Commands
|
79
|
+
|
80
|
+
### 1. `echo` - Echo Command
|
81
|
+
|
82
|
+
Returns the provided message.
|
83
|
+
|
84
|
+
**Parameters:**
|
85
|
+
- `message` (string) - Message to echo back
|
86
|
+
|
87
|
+
**Example request:**
|
88
|
+
```json
|
89
|
+
{
|
90
|
+
"jsonrpc": "2.0",
|
91
|
+
"method": "echo",
|
92
|
+
"params": {
|
93
|
+
"message": "Hello, World!"
|
94
|
+
},
|
95
|
+
"id": 1
|
96
|
+
}
|
97
|
+
```
|
98
|
+
|
99
|
+
### 2. `math` - Math Command
|
100
|
+
|
101
|
+
Performs a math operation on two numbers.
|
102
|
+
|
103
|
+
**Parameters:**
|
104
|
+
- `a` (number) - First number
|
105
|
+
- `b` (number) - Second number
|
106
|
+
- `operation` (string) - Operation (add, subtract, multiply, divide)
|
107
|
+
|
108
|
+
**Example request:**
|
109
|
+
```json
|
110
|
+
{
|
111
|
+
"jsonrpc": "2.0",
|
112
|
+
"method": "math",
|
113
|
+
"params": {
|
114
|
+
"a": 10,
|
115
|
+
"b": 5,
|
116
|
+
"operation": "add"
|
117
|
+
},
|
118
|
+
"id": 1
|
119
|
+
}
|
120
|
+
```
|
121
|
+
|
122
|
+
### 3. `time` - Time Command
|
123
|
+
|
124
|
+
Returns the current time and date.
|
125
|
+
|
126
|
+
**Parameters:**
|
127
|
+
- `format` (string, optional) - Time format (default: "%Y-%m-%d %H:%M:%S")
|
128
|
+
- `timezone` (string, optional) - Timezone (default: "UTC")
|
129
|
+
|
130
|
+
**Example request:**
|
131
|
+
```json
|
132
|
+
{
|
133
|
+
"jsonrpc": "2.0",
|
134
|
+
"method": "time",
|
135
|
+
"params": {
|
136
|
+
"format": "%d.%m.%Y %H:%M:%S",
|
137
|
+
"timezone": "Europe/London"
|
138
|
+
},
|
139
|
+
"id": 1
|
140
|
+
}
|
141
|
+
```
|
142
|
+
|
143
|
+
## Testing the API
|
144
|
+
|
145
|
+
### Via Web Interface
|
146
|
+
|
147
|
+
Open [http://localhost:8000/docs](http://localhost:8000/docs) in your browser to access the Swagger UI interactive documentation.
|
148
|
+
|
149
|
+
### Via Command Line
|
150
|
+
|
151
|
+
```bash
|
152
|
+
# Call echo command via JSON-RPC
|
153
|
+
curl -X POST "http://localhost:8000/api/jsonrpc" \
|
154
|
+
-H "Content-Type: application/json" \
|
155
|
+
-d '{"jsonrpc": "2.0", "method": "echo", "params": {"message": "Hello!"}, "id": 1}'
|
156
|
+
|
157
|
+
# Call math command via simplified endpoint
|
158
|
+
curl -X POST "http://localhost:8000/cmd" \
|
159
|
+
-H "Content-Type: application/json" \
|
160
|
+
-d '{"command": "math", "params": {"a": 10, "b": 5, "operation": "add"}}'
|
161
|
+
|
162
|
+
# Call time command via endpoint /api/command/{command_name}
|
163
|
+
curl -X POST "http://localhost:8000/api/command/time" \
|
164
|
+
-H "Content-Type: application/json" \
|
165
|
+
-d '{"format": "%d.%m.%Y %H:%M:%S", "timezone": "UTC"}'
|
166
|
+
```
|
167
|
+
|
168
|
+
## Key Features Demonstrated
|
169
|
+
|
170
|
+
1. Command organization in separate files
|
171
|
+
2. Automatic command discovery and registration
|
172
|
+
3. Different command types and parameter handling
|
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
|
@@ -0,0 +1,177 @@
|
|
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.json # Файл конфигурации JSON
|
16
|
+
├── docs/ # Документация
|
17
|
+
│ ├── EN/ # Английская документация
|
18
|
+
│ │ └── README.md # Английская версия данного файла
|
19
|
+
│ └── RU/ # Русская документация
|
20
|
+
│ └── README.md # Этот файл
|
21
|
+
├── logs/ # Директория для логов
|
22
|
+
├── server.py # Файл запуска сервера и логики приложения
|
23
|
+
└── tests/ # Директория с тестами
|
24
|
+
└── conftest.py # Конфигурация и фикстуры для тестов
|
25
|
+
```
|
26
|
+
|
27
|
+
## Запуск примера
|
28
|
+
|
29
|
+
```bash
|
30
|
+
# Перейти в директорию проекта
|
31
|
+
cd examples/basic_example
|
32
|
+
|
33
|
+
# Создать директорию для логов, если она не существует
|
34
|
+
mkdir -p logs
|
35
|
+
|
36
|
+
# Запустить сервер с конфигурацией по умолчанию (config.json)
|
37
|
+
python server.py
|
38
|
+
|
39
|
+
# Или запустить с указанием другого файла конфигурации
|
40
|
+
python server.py --config другой_конфиг.json
|
41
|
+
```
|
42
|
+
|
43
|
+
После запуска сервер будет доступен по адресу [http://localhost:8000](http://localhost:8000).
|
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
|
+
|
78
|
+
## Доступные команды
|
79
|
+
|
80
|
+
### 1. `echo` - Эхо-команда
|
81
|
+
|
82
|
+
Возвращает переданное сообщение.
|
83
|
+
|
84
|
+
**Параметры:**
|
85
|
+
- `message` (string) - Сообщение для эхо
|
86
|
+
|
87
|
+
**Пример запроса:**
|
88
|
+
```json
|
89
|
+
{
|
90
|
+
"jsonrpc": "2.0",
|
91
|
+
"method": "echo",
|
92
|
+
"params": {
|
93
|
+
"message": "Hello, World!"
|
94
|
+
},
|
95
|
+
"id": 1
|
96
|
+
}
|
97
|
+
```
|
98
|
+
|
99
|
+
### 2. `math` - Математическая команда
|
100
|
+
|
101
|
+
Выполняет математическую операцию над двумя числами.
|
102
|
+
|
103
|
+
**Параметры:**
|
104
|
+
- `a` (number) - Первое число
|
105
|
+
- `b` (number) - Второе число
|
106
|
+
- `operation` (string) - Операция (add, subtract, multiply, divide)
|
107
|
+
|
108
|
+
**Пример запроса:**
|
109
|
+
```json
|
110
|
+
{
|
111
|
+
"jsonrpc": "2.0",
|
112
|
+
"method": "math",
|
113
|
+
"params": {
|
114
|
+
"a": 10,
|
115
|
+
"b": 5,
|
116
|
+
"operation": "add"
|
117
|
+
},
|
118
|
+
"id": 1
|
119
|
+
}
|
120
|
+
```
|
121
|
+
|
122
|
+
### 3. `time` - Команда времени
|
123
|
+
|
124
|
+
Возвращает текущее время и дату.
|
125
|
+
|
126
|
+
**Параметры:**
|
127
|
+
- `format` (string, опционально) - Формат времени (по умолчанию: "%Y-%m-%d %H:%M:%S")
|
128
|
+
- `timezone` (string, опционально) - Часовой пояс (по умолчанию: "UTC")
|
129
|
+
|
130
|
+
**Пример запроса:**
|
131
|
+
```json
|
132
|
+
{
|
133
|
+
"jsonrpc": "2.0",
|
134
|
+
"method": "time",
|
135
|
+
"params": {
|
136
|
+
"format": "%d.%m.%Y %H:%M:%S",
|
137
|
+
"timezone": "Europe/Moscow"
|
138
|
+
},
|
139
|
+
"id": 1
|
140
|
+
}
|
141
|
+
```
|
142
|
+
|
143
|
+
## Тестирование API
|
144
|
+
|
145
|
+
### Через веб-интерфейс
|
146
|
+
|
147
|
+
Откройте в браузере [http://localhost:8000/docs](http://localhost:8000/docs) для доступа к интерактивной документации Swagger UI.
|
148
|
+
|
149
|
+
### Через командную строку
|
150
|
+
|
151
|
+
```bash
|
152
|
+
# Вызов команды echo через JSON-RPC
|
153
|
+
curl -X POST "http://localhost:8000/api/jsonrpc" \
|
154
|
+
-H "Content-Type: application/json" \
|
155
|
+
-d '{"jsonrpc": "2.0", "method": "echo", "params": {"message": "Hello!"}, "id": 1}'
|
156
|
+
|
157
|
+
# Вызов команды math через упрощенный эндпоинт
|
158
|
+
curl -X POST "http://localhost:8000/cmd" \
|
159
|
+
-H "Content-Type: application/json" \
|
160
|
+
-d '{"command": "math", "params": {"a": 10, "b": 5, "operation": "add"}}'
|
161
|
+
|
162
|
+
# Вызов команды time через endpoint /api/command/{command_name}
|
163
|
+
curl -X POST "http://localhost:8000/api/command/time" \
|
164
|
+
-H "Content-Type: application/json" \
|
165
|
+
-d '{"format": "%d.%m.%Y %H:%M:%S", "timezone": "UTC"}'
|
166
|
+
```
|
167
|
+
|
168
|
+
## Ключевые особенности, демонстрируемые примером
|
169
|
+
|
170
|
+
1. Организация команд в отдельные файлы
|
171
|
+
2. Автоматическое обнаружение и регистрация команд
|
172
|
+
3. Различные типы команд и параметров
|
173
|
+
4. Обработка ошибок и автоматическая перерегистрация команд
|
174
|
+
5. Различные способы вызова команд (JSON-RPC, /cmd, /api/command/{command_name})
|
175
|
+
6. Поддержка режима отладки с горячей перезагрузкой
|
176
|
+
7. Безопасная регистрация команд для предотвращения конфликтов
|
177
|
+
8. JSON-файлы конфигурации с опциями командной строки
|
@@ -0,0 +1,151 @@
|
|
1
|
+
"""
|
2
|
+
Basic MCP Proxy Adapter example.
|
3
|
+
|
4
|
+
This example demonstrates how to use MCP Proxy Adapter to create
|
5
|
+
a microservice with multiple commands organized in separate files.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import os
|
9
|
+
import sys
|
10
|
+
import json
|
11
|
+
import argparse
|
12
|
+
import uvicorn
|
13
|
+
from typing import Dict, Any
|
14
|
+
from pathlib import Path
|
15
|
+
|
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
|
20
|
+
|
21
|
+
# Add commands directory to path for local imports
|
22
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
23
|
+
|
24
|
+
|
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
|
+
|
50
|
+
# Get absolute paths
|
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
|
60
|
+
|
61
|
+
# Create log directory if it doesn't exist
|
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"
|
85
|
+
|
86
|
+
# Discover and register commands from the commands directory
|
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}")
|
123
|
+
|
124
|
+
# Run server
|
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
|
+
)
|
148
|
+
|
149
|
+
|
150
|
+
if __name__ == "__main__":
|
151
|
+
main()
|