mcp-proxy-adapter 4.1.1__py3-none-any.whl → 6.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_proxy_adapter/__main__.py +12 -0
- mcp_proxy_adapter/api/app.py +138 -11
- mcp_proxy_adapter/api/handlers.py +16 -1
- mcp_proxy_adapter/api/middleware/__init__.py +30 -29
- mcp_proxy_adapter/api/middleware/auth_adapter.py +235 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +9 -0
- mcp_proxy_adapter/api/middleware/factory.py +219 -0
- mcp_proxy_adapter/api/middleware/logging.py +32 -6
- mcp_proxy_adapter/api/middleware/mtls_adapter.py +305 -0
- mcp_proxy_adapter/api/middleware/mtls_middleware.py +296 -0
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +135 -0
- mcp_proxy_adapter/api/middleware/rate_limit_adapter.py +241 -0
- mcp_proxy_adapter/api/middleware/roles_adapter.py +365 -0
- mcp_proxy_adapter/api/middleware/roles_middleware.py +381 -0
- mcp_proxy_adapter/api/middleware/security.py +376 -0
- mcp_proxy_adapter/api/middleware/token_auth_middleware.py +261 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +122 -0
- mcp_proxy_adapter/commands/__init__.py +13 -4
- mcp_proxy_adapter/commands/auth_validation_command.py +408 -0
- mcp_proxy_adapter/commands/base.py +61 -30
- mcp_proxy_adapter/commands/builtin_commands.py +89 -0
- mcp_proxy_adapter/commands/catalog_manager.py +838 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +620 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +608 -0
- mcp_proxy_adapter/commands/command_registry.py +703 -354
- mcp_proxy_adapter/commands/dependency_manager.py +245 -0
- mcp_proxy_adapter/commands/health_command.py +7 -0
- mcp_proxy_adapter/commands/hooks.py +200 -167
- mcp_proxy_adapter/commands/key_management_command.py +506 -0
- mcp_proxy_adapter/commands/load_command.py +176 -0
- mcp_proxy_adapter/commands/plugins_command.py +235 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +232 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +268 -0
- mcp_proxy_adapter/commands/reload_command.py +48 -50
- mcp_proxy_adapter/commands/result.py +1 -0
- mcp_proxy_adapter/commands/roles_management_command.py +697 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +483 -0
- mcp_proxy_adapter/commands/token_management_command.py +529 -0
- mcp_proxy_adapter/commands/transport_management_command.py +144 -0
- mcp_proxy_adapter/commands/unload_command.py +158 -0
- mcp_proxy_adapter/config.py +99 -2
- mcp_proxy_adapter/core/auth_validator.py +606 -0
- mcp_proxy_adapter/core/certificate_utils.py +827 -0
- mcp_proxy_adapter/core/config_converter.py +405 -0
- mcp_proxy_adapter/core/config_validator.py +218 -0
- mcp_proxy_adapter/core/logging.py +11 -0
- mcp_proxy_adapter/core/protocol_manager.py +226 -0
- mcp_proxy_adapter/core/proxy_registration.py +270 -0
- mcp_proxy_adapter/core/role_utils.py +426 -0
- mcp_proxy_adapter/core/security_adapter.py +373 -0
- mcp_proxy_adapter/core/security_factory.py +239 -0
- mcp_proxy_adapter/core/settings.py +1 -0
- mcp_proxy_adapter/core/ssl_utils.py +233 -0
- mcp_proxy_adapter/core/transport_manager.py +292 -0
- mcp_proxy_adapter/custom_openapi.py +22 -11
- mcp_proxy_adapter/examples/basic_server/config.json +58 -23
- mcp_proxy_adapter/examples/basic_server/config_all_protocols.json +54 -0
- mcp_proxy_adapter/examples/basic_server/config_http.json +70 -0
- mcp_proxy_adapter/examples/basic_server/config_http_only.json +52 -0
- mcp_proxy_adapter/examples/basic_server/config_https.json +58 -0
- mcp_proxy_adapter/examples/basic_server/config_mtls.json +58 -0
- mcp_proxy_adapter/examples/basic_server/config_ssl.json +46 -0
- mcp_proxy_adapter/examples/basic_server/server.py +12 -1
- mcp_proxy_adapter/examples/custom_commands/__init__.py +1 -1
- mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +339 -23
- mcp_proxy_adapter/examples/custom_commands/auto_commands/test_command.py +105 -0
- mcp_proxy_adapter/examples/custom_commands/catalog/commands/test_command.py +129 -0
- mcp_proxy_adapter/examples/custom_commands/config.json +101 -18
- mcp_proxy_adapter/examples/custom_commands/config_all_protocols.json +46 -0
- mcp_proxy_adapter/examples/custom_commands/config_https_only.json +46 -0
- mcp_proxy_adapter/examples/custom_commands/config_https_transport.json +33 -0
- mcp_proxy_adapter/examples/custom_commands/config_mtls_only.json +46 -0
- mcp_proxy_adapter/examples/custom_commands/config_mtls_transport.json +33 -0
- mcp_proxy_adapter/examples/custom_commands/config_single_transport.json +33 -0
- mcp_proxy_adapter/examples/custom_commands/full_help_response.json +1 -0
- mcp_proxy_adapter/examples/custom_commands/generated_openapi.json +629 -0
- mcp_proxy_adapter/examples/custom_commands/get_openapi.py +103 -0
- mcp_proxy_adapter/examples/custom_commands/loadable_commands/test_ignored.py +129 -0
- mcp_proxy_adapter/examples/custom_commands/proxy_connection_manager.py +278 -0
- mcp_proxy_adapter/examples/custom_commands/server.py +92 -68
- mcp_proxy_adapter/examples/custom_commands/simple_openapi_server.py +75 -0
- mcp_proxy_adapter/examples/custom_commands/start_server_with_proxy_manager.py +299 -0
- mcp_proxy_adapter/examples/custom_commands/start_server_with_registration.py +278 -0
- mcp_proxy_adapter/examples/custom_commands/test_openapi.py +27 -0
- mcp_proxy_adapter/examples/custom_commands/test_registry.py +23 -0
- mcp_proxy_adapter/examples/custom_commands/test_simple.py +19 -0
- mcp_proxy_adapter/examples/custom_project_example/README.md +103 -0
- mcp_proxy_adapter/examples/custom_project_example/README_EN.md +103 -0
- mcp_proxy_adapter/examples/simple_custom_commands/README.md +149 -0
- mcp_proxy_adapter/examples/simple_custom_commands/README_EN.md +149 -0
- mcp_proxy_adapter/main.py +175 -0
- mcp_proxy_adapter/schemas/roles_schema.json +162 -0
- mcp_proxy_adapter/tests/unit/test_config.py +53 -0
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.0.dist-info}/METADATA +2 -1
- mcp_proxy_adapter-6.0.0.dist-info/RECORD +179 -0
- mcp_proxy_adapter/commands/reload_settings_command.py +0 -125
- mcp_proxy_adapter-4.1.1.dist-info/RECORD +0 -110
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.0.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.0.dist-info}/licenses/LICENSE +0 -0
- {mcp_proxy_adapter-4.1.1.dist-info → mcp_proxy_adapter-6.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,149 @@
|
|
1
|
+
# Простой пример с пользовательскими командами
|
2
|
+
|
3
|
+
Этот пример показывает, как настроить `discovery_path` в конфигурации для автоматического обнаружения команд из вашего проекта.
|
4
|
+
|
5
|
+
## Структура проекта
|
6
|
+
|
7
|
+
```
|
8
|
+
simple_custom_commands/
|
9
|
+
├── config.json # Конфигурация с discovery_path
|
10
|
+
├── main.py # Точка входа
|
11
|
+
├── my_commands/ # Пакет с командами
|
12
|
+
│ ├── __init__.py
|
13
|
+
│ ├── hello_command.py
|
14
|
+
│ └── calc_command.py
|
15
|
+
└── README.md
|
16
|
+
```
|
17
|
+
|
18
|
+
## Конфигурация (config.json)
|
19
|
+
|
20
|
+
```json
|
21
|
+
{
|
22
|
+
"server": {
|
23
|
+
"host": "127.0.0.1",
|
24
|
+
"port": 8001,
|
25
|
+
"debug": true,
|
26
|
+
"log_level": "DEBUG"
|
27
|
+
},
|
28
|
+
"logging": {
|
29
|
+
"level": "DEBUG",
|
30
|
+
"log_dir": "./logs",
|
31
|
+
"log_file": "simple_commands.log"
|
32
|
+
},
|
33
|
+
"commands": {
|
34
|
+
"auto_discovery": true,
|
35
|
+
"discovery_path": "my_commands"
|
36
|
+
}
|
37
|
+
}
|
38
|
+
```
|
39
|
+
|
40
|
+
**Ключевой момент**: В `discovery_path` указан путь `"my_commands"` - это пакет, где находятся команды.
|
41
|
+
|
42
|
+
## Команды
|
43
|
+
|
44
|
+
### hello_command.py
|
45
|
+
|
46
|
+
```python
|
47
|
+
from mcp_proxy_adapter.commands.base import Command
|
48
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
49
|
+
|
50
|
+
class HelloCommand(Command):
|
51
|
+
"""Простая команда приветствия."""
|
52
|
+
|
53
|
+
name = "hello"
|
54
|
+
|
55
|
+
def execute(self, name: str = "World") -> CommandResult:
|
56
|
+
return CommandResult(
|
57
|
+
success=True,
|
58
|
+
data={"message": f"Hello, {name}!"}
|
59
|
+
)
|
60
|
+
|
61
|
+
@classmethod
|
62
|
+
def get_param_info(cls) -> dict:
|
63
|
+
return {
|
64
|
+
"name": {
|
65
|
+
"type": "string",
|
66
|
+
"description": "Имя для приветствия",
|
67
|
+
"required": False,
|
68
|
+
"default": "World"
|
69
|
+
}
|
70
|
+
}
|
71
|
+
```
|
72
|
+
|
73
|
+
### calc_command.py
|
74
|
+
|
75
|
+
```python
|
76
|
+
from mcp_proxy_adapter.commands.base import Command
|
77
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
78
|
+
|
79
|
+
class CalcCommand(Command):
|
80
|
+
"""Простая команда калькулятора."""
|
81
|
+
|
82
|
+
name = "calc"
|
83
|
+
|
84
|
+
def execute(self, a: float, b: float, operation: str = "add") -> CommandResult:
|
85
|
+
if operation == "add":
|
86
|
+
result = a + b
|
87
|
+
elif operation == "sub":
|
88
|
+
result = a - b
|
89
|
+
elif operation == "mul":
|
90
|
+
result = a * b
|
91
|
+
elif operation == "div":
|
92
|
+
if b == 0:
|
93
|
+
return CommandResult(success=False, error="Division by zero")
|
94
|
+
result = a / b
|
95
|
+
else:
|
96
|
+
return CommandResult(success=False, error=f"Unknown operation: {operation}")
|
97
|
+
|
98
|
+
return CommandResult(
|
99
|
+
success=True,
|
100
|
+
data={"result": result, "operation": operation}
|
101
|
+
)
|
102
|
+
|
103
|
+
@classmethod
|
104
|
+
def get_param_info(cls) -> dict:
|
105
|
+
return {
|
106
|
+
"a": {
|
107
|
+
"type": "number",
|
108
|
+
"description": "Первое число",
|
109
|
+
"required": True
|
110
|
+
},
|
111
|
+
"b": {
|
112
|
+
"type": "number",
|
113
|
+
"description": "Второе число",
|
114
|
+
"required": True
|
115
|
+
},
|
116
|
+
"operation": {
|
117
|
+
"type": "string",
|
118
|
+
"description": "Операция (add, sub, mul, div)",
|
119
|
+
"required": False,
|
120
|
+
"default": "add"
|
121
|
+
}
|
122
|
+
}
|
123
|
+
```
|
124
|
+
|
125
|
+
## Запуск
|
126
|
+
|
127
|
+
```bash
|
128
|
+
python main.py
|
129
|
+
```
|
130
|
+
|
131
|
+
При запуске сервис автоматически обнаружит команды из пакета `my_commands` благодаря настройке `discovery_path` в конфигурации.
|
132
|
+
|
133
|
+
## Тестирование
|
134
|
+
|
135
|
+
```bash
|
136
|
+
# Приветствие
|
137
|
+
curl -X POST http://127.0.0.1:8001/cmd \
|
138
|
+
-H "Content-Type: application/json" \
|
139
|
+
-d '{"command": "hello", "params": {"name": "Alice"}}'
|
140
|
+
|
141
|
+
# Калькулятор
|
142
|
+
curl -X POST http://127.0.0.1:8001/cmd \
|
143
|
+
-H "Content-Type: application/json" \
|
144
|
+
-d '{"command": "calc", "params": {"a": 10, "b": 5, "operation": "add"}}'
|
145
|
+
```
|
146
|
+
|
147
|
+
## Результат
|
148
|
+
|
149
|
+
Сервис автоматически обнаружит и зарегистрирует команды `hello` и `calc` из пакета `my_commands`, указанного в `discovery_path`.
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# Simple Custom Commands Example
|
2
|
+
|
3
|
+
This example shows how to configure `discovery_path` in the configuration for automatic discovery of commands from your project.
|
4
|
+
|
5
|
+
## Project Structure
|
6
|
+
|
7
|
+
```
|
8
|
+
simple_custom_commands/
|
9
|
+
├── config.json # Configuration with discovery_path
|
10
|
+
├── main.py # Entry point
|
11
|
+
├── my_commands/ # Package with commands
|
12
|
+
│ ├── __init__.py
|
13
|
+
│ ├── hello_command.py
|
14
|
+
│ └── calc_command.py
|
15
|
+
└── README.md
|
16
|
+
```
|
17
|
+
|
18
|
+
## Configuration (config.json)
|
19
|
+
|
20
|
+
```json
|
21
|
+
{
|
22
|
+
"server": {
|
23
|
+
"host": "127.0.0.1",
|
24
|
+
"port": 8001,
|
25
|
+
"debug": true,
|
26
|
+
"log_level": "DEBUG"
|
27
|
+
},
|
28
|
+
"logging": {
|
29
|
+
"level": "DEBUG",
|
30
|
+
"log_dir": "./logs",
|
31
|
+
"log_file": "simple_commands.log"
|
32
|
+
},
|
33
|
+
"commands": {
|
34
|
+
"auto_discovery": true,
|
35
|
+
"discovery_path": "my_commands"
|
36
|
+
}
|
37
|
+
}
|
38
|
+
```
|
39
|
+
|
40
|
+
**Key point**: In `discovery_path` we specify `"my_commands"` - this is the package where commands are located.
|
41
|
+
|
42
|
+
## Commands
|
43
|
+
|
44
|
+
### hello_command.py
|
45
|
+
|
46
|
+
```python
|
47
|
+
from mcp_proxy_adapter.commands.base import Command
|
48
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
49
|
+
|
50
|
+
class HelloCommand(Command):
|
51
|
+
"""Simple greeting command."""
|
52
|
+
|
53
|
+
name = "hello"
|
54
|
+
|
55
|
+
def execute(self, name: str = "World") -> CommandResult:
|
56
|
+
return CommandResult(
|
57
|
+
success=True,
|
58
|
+
data={"message": f"Hello, {name}!"}
|
59
|
+
)
|
60
|
+
|
61
|
+
@classmethod
|
62
|
+
def get_param_info(cls) -> dict:
|
63
|
+
return {
|
64
|
+
"name": {
|
65
|
+
"type": "string",
|
66
|
+
"description": "Name for greeting",
|
67
|
+
"required": False,
|
68
|
+
"default": "World"
|
69
|
+
}
|
70
|
+
}
|
71
|
+
```
|
72
|
+
|
73
|
+
### calc_command.py
|
74
|
+
|
75
|
+
```python
|
76
|
+
from mcp_proxy_adapter.commands.base import Command
|
77
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
78
|
+
|
79
|
+
class CalcCommand(Command):
|
80
|
+
"""Simple calculator command."""
|
81
|
+
|
82
|
+
name = "calc"
|
83
|
+
|
84
|
+
def execute(self, a: float, b: float, operation: str = "add") -> CommandResult:
|
85
|
+
if operation == "add":
|
86
|
+
result = a + b
|
87
|
+
elif operation == "sub":
|
88
|
+
result = a - b
|
89
|
+
elif operation == "mul":
|
90
|
+
result = a * b
|
91
|
+
elif operation == "div":
|
92
|
+
if b == 0:
|
93
|
+
return CommandResult(success=False, error="Division by zero")
|
94
|
+
result = a / b
|
95
|
+
else:
|
96
|
+
return CommandResult(success=False, error=f"Unknown operation: {operation}")
|
97
|
+
|
98
|
+
return CommandResult(
|
99
|
+
success=True,
|
100
|
+
data={"result": result, "operation": operation}
|
101
|
+
)
|
102
|
+
|
103
|
+
@classmethod
|
104
|
+
def get_param_info(cls) -> dict:
|
105
|
+
return {
|
106
|
+
"a": {
|
107
|
+
"type": "number",
|
108
|
+
"description": "First number",
|
109
|
+
"required": True
|
110
|
+
},
|
111
|
+
"b": {
|
112
|
+
"type": "number",
|
113
|
+
"description": "Second number",
|
114
|
+
"required": True
|
115
|
+
},
|
116
|
+
"operation": {
|
117
|
+
"type": "string",
|
118
|
+
"description": "Operation (add, sub, mul, div)",
|
119
|
+
"required": False,
|
120
|
+
"default": "add"
|
121
|
+
}
|
122
|
+
}
|
123
|
+
```
|
124
|
+
|
125
|
+
## Running
|
126
|
+
|
127
|
+
```bash
|
128
|
+
python main.py
|
129
|
+
```
|
130
|
+
|
131
|
+
When starting, the service will automatically discover commands from the `my_commands` package thanks to the `discovery_path` configuration setting.
|
132
|
+
|
133
|
+
## Testing
|
134
|
+
|
135
|
+
```bash
|
136
|
+
# Greeting
|
137
|
+
curl -X POST http://127.0.0.1:8001/cmd \
|
138
|
+
-H "Content-Type: application/json" \
|
139
|
+
-d '{"command": "hello", "params": {"name": "Alice"}}'
|
140
|
+
|
141
|
+
# Calculator
|
142
|
+
curl -X POST http://127.0.0.1:8001/cmd \
|
143
|
+
-H "Content-Type: application/json" \
|
144
|
+
-d '{"command": "calc", "params": {"a": 10, "b": 5, "operation": "add"}}'
|
145
|
+
```
|
146
|
+
|
147
|
+
## Result
|
148
|
+
|
149
|
+
The service will automatically discover and register the `hello` and `calc` commands from the `my_commands` package specified in `discovery_path`.
|
@@ -0,0 +1,175 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Main entry point for MCP Proxy Adapter.
|
4
|
+
|
5
|
+
This module provides the main function for running the MCP Proxy Adapter server.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import argparse
|
9
|
+
import asyncio
|
10
|
+
import uvicorn
|
11
|
+
import sys
|
12
|
+
import os
|
13
|
+
from pathlib import Path
|
14
|
+
|
15
|
+
from mcp_proxy_adapter import create_app
|
16
|
+
from mcp_proxy_adapter.core.logging import get_logger, setup_logging
|
17
|
+
from mcp_proxy_adapter.core.settings import (
|
18
|
+
Settings,
|
19
|
+
get_server_host,
|
20
|
+
get_server_port,
|
21
|
+
get_server_debug,
|
22
|
+
get_setting
|
23
|
+
)
|
24
|
+
from mcp_proxy_adapter.core.ssl_utils import SSLUtils
|
25
|
+
|
26
|
+
|
27
|
+
def parse_args():
|
28
|
+
"""Parse command line arguments."""
|
29
|
+
parser = argparse.ArgumentParser(description="MCP Proxy Adapter Server")
|
30
|
+
parser.add_argument(
|
31
|
+
"--config",
|
32
|
+
type=str,
|
33
|
+
default=None,
|
34
|
+
help="Path to configuration file"
|
35
|
+
)
|
36
|
+
parser.add_argument(
|
37
|
+
"--host",
|
38
|
+
type=str,
|
39
|
+
default=None,
|
40
|
+
help="Host to bind to (overrides config)"
|
41
|
+
)
|
42
|
+
parser.add_argument(
|
43
|
+
"--port",
|
44
|
+
type=int,
|
45
|
+
default=None,
|
46
|
+
help="Port to bind to (overrides config)"
|
47
|
+
)
|
48
|
+
parser.add_argument(
|
49
|
+
"--debug",
|
50
|
+
action="store_true",
|
51
|
+
help="Enable debug mode (overrides config)"
|
52
|
+
)
|
53
|
+
parser.add_argument(
|
54
|
+
"--log-level",
|
55
|
+
type=str,
|
56
|
+
default=None,
|
57
|
+
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
58
|
+
help="Log level (overrides config)"
|
59
|
+
)
|
60
|
+
return parser.parse_args()
|
61
|
+
|
62
|
+
|
63
|
+
def main():
|
64
|
+
"""Run the MCP Proxy Adapter server."""
|
65
|
+
args = parse_args()
|
66
|
+
|
67
|
+
# Load configuration if specified
|
68
|
+
if args.config:
|
69
|
+
config_path = Path(args.config)
|
70
|
+
if config_path.exists():
|
71
|
+
from mcp_proxy_adapter.config import config
|
72
|
+
config.load_from_file(str(config_path))
|
73
|
+
print(f"✅ Loaded configuration from: {config_path}")
|
74
|
+
else:
|
75
|
+
print(f"❌ Configuration file not found: {config_path}")
|
76
|
+
sys.exit(1)
|
77
|
+
else:
|
78
|
+
print("⚠️ No configuration file specified, using defaults")
|
79
|
+
|
80
|
+
# Setup logging with configuration
|
81
|
+
setup_logging()
|
82
|
+
logger = get_logger("mcp_proxy_adapter")
|
83
|
+
|
84
|
+
# Get settings from configuration
|
85
|
+
server_settings = Settings.get_server_settings()
|
86
|
+
logging_settings = Settings.get_logging_settings()
|
87
|
+
commands_settings = Settings.get_commands_settings()
|
88
|
+
ssl_settings = Settings.get_custom_setting("ssl", {})
|
89
|
+
security_settings = Settings.get_custom_setting("security", {})
|
90
|
+
|
91
|
+
# STRICT CONFIGURATION VALIDATION
|
92
|
+
from mcp_proxy_adapter.core.config_validator import ConfigValidator
|
93
|
+
|
94
|
+
# Get full config for validation
|
95
|
+
full_config = {
|
96
|
+
"server": server_settings,
|
97
|
+
"logging": logging_settings,
|
98
|
+
"commands": commands_settings,
|
99
|
+
"ssl": ssl_settings,
|
100
|
+
"security": security_settings,
|
101
|
+
"auth_enabled": Settings.get_custom_setting("auth_enabled", False),
|
102
|
+
"roles": Settings.get_custom_setting("roles", {})
|
103
|
+
}
|
104
|
+
|
105
|
+
# Validate configuration
|
106
|
+
validator = ConfigValidator(full_config)
|
107
|
+
if not validator.validate_all():
|
108
|
+
logger.critical("CRITICAL SECURITY ERROR: Configuration validation failed")
|
109
|
+
validator.print_validation_report()
|
110
|
+
logger.critical("Server startup blocked for security reasons.")
|
111
|
+
logger.critical("Please fix configuration errors or disable security features.")
|
112
|
+
sys.exit(1)
|
113
|
+
|
114
|
+
logger.info("Configuration validation passed")
|
115
|
+
|
116
|
+
# Override settings with command line arguments
|
117
|
+
if args.host:
|
118
|
+
server_settings['host'] = args.host
|
119
|
+
if args.port:
|
120
|
+
server_settings['port'] = args.port
|
121
|
+
if args.debug:
|
122
|
+
server_settings['debug'] = True
|
123
|
+
if args.log_level:
|
124
|
+
logging_settings['level'] = args.log_level
|
125
|
+
server_settings['log_level'] = args.log_level
|
126
|
+
|
127
|
+
# Print server header and description
|
128
|
+
print("=" * 80)
|
129
|
+
print("🚀 MCP PROXY ADAPTER SERVER")
|
130
|
+
print("=" * 80)
|
131
|
+
print("📋 Configuration:")
|
132
|
+
print(f" • Server: {server_settings['host']}:{server_settings['port']}")
|
133
|
+
print(f" • Debug: {server_settings['debug']}")
|
134
|
+
print(f" • Log Level: {logging_settings['level']}")
|
135
|
+
print(f" • Auto Discovery: {commands_settings['auto_discovery']}")
|
136
|
+
print(f" • SSL Enabled: {ssl_settings.get('enabled', False)}")
|
137
|
+
print(f" • Security Enabled: {security_settings.get('enabled', False)}")
|
138
|
+
if ssl_settings.get('enabled', False):
|
139
|
+
print(f" • SSL Mode: {ssl_settings.get('mode', 'https_only')}")
|
140
|
+
if security_settings.get('enabled', False):
|
141
|
+
print(f" • Security Framework: {security_settings.get('framework', 'built-in')}")
|
142
|
+
print("=" * 80)
|
143
|
+
print()
|
144
|
+
|
145
|
+
logger.info("Starting MCP Proxy Adapter Server...")
|
146
|
+
logger.info(f"Server configuration: {server_settings}")
|
147
|
+
logger.info(f"Security configuration: {security_settings}")
|
148
|
+
|
149
|
+
try:
|
150
|
+
# Create application
|
151
|
+
app = create_app(
|
152
|
+
title="MCP Proxy Adapter Server",
|
153
|
+
description="Model Context Protocol Proxy Adapter with Security Framework",
|
154
|
+
version="1.0.0"
|
155
|
+
)
|
156
|
+
|
157
|
+
# Get SSL configuration for uvicorn
|
158
|
+
uvicorn_ssl_config = SSLUtils.get_ssl_config_for_uvicorn(ssl_settings)
|
159
|
+
|
160
|
+
# Run the server
|
161
|
+
uvicorn.run(
|
162
|
+
app,
|
163
|
+
host=server_settings['host'],
|
164
|
+
port=server_settings['port'],
|
165
|
+
log_level=server_settings.get('log_level', 'info').lower(),
|
166
|
+
**uvicorn_ssl_config
|
167
|
+
)
|
168
|
+
|
169
|
+
except Exception as e:
|
170
|
+
logger.error(f"Failed to start server: {e}")
|
171
|
+
sys.exit(1)
|
172
|
+
|
173
|
+
|
174
|
+
if __name__ == "__main__":
|
175
|
+
main()
|
@@ -0,0 +1,162 @@
|
|
1
|
+
{
|
2
|
+
"roles": {
|
3
|
+
"admin": {
|
4
|
+
"description": "Administrator with full access",
|
5
|
+
"allowed_servers": ["*"],
|
6
|
+
"allowed_clients": ["*"],
|
7
|
+
"permissions": ["read", "write", "delete", "admin"],
|
8
|
+
"priority": 100
|
9
|
+
},
|
10
|
+
"super-admin": {
|
11
|
+
"description": "Super administrator with system-level access",
|
12
|
+
"allowed_servers": ["*"],
|
13
|
+
"allowed_clients": ["*"],
|
14
|
+
"permissions": ["read", "write", "delete", "admin", "system"],
|
15
|
+
"priority": 200
|
16
|
+
},
|
17
|
+
"kubernetes_service": {
|
18
|
+
"description": "Kubernetes service with cluster management access",
|
19
|
+
"allowed_servers": ["kubernetes_manager", "kubernetes_api", "cluster_monitor", "k8s_operator"],
|
20
|
+
"allowed_clients": ["admin", "super-admin", "kubernetes_service", "ca_root", "ca_intermediate"],
|
21
|
+
"permissions": ["read", "write", "system"],
|
22
|
+
"priority": 120
|
23
|
+
},
|
24
|
+
"ca_root": {
|
25
|
+
"description": "Root Certificate Authority with full certificate management",
|
26
|
+
"allowed_servers": ["*"],
|
27
|
+
"allowed_clients": ["admin", "super-admin", "ca_root", "ca_intermediate"],
|
28
|
+
"permissions": ["read", "write", "delete", "admin", "system"],
|
29
|
+
"priority": 180
|
30
|
+
},
|
31
|
+
"ca_intermediate": {
|
32
|
+
"description": "Intermediate Certificate Authority with delegated certificate management",
|
33
|
+
"allowed_servers": ["certificate_manager", "ssl_manager", "tls_manager"],
|
34
|
+
"allowed_clients": ["admin", "super-admin", "ca_root", "ca_intermediate", "kubernetes_service"],
|
35
|
+
"permissions": ["read", "write", "admin"],
|
36
|
+
"priority": 140
|
37
|
+
},
|
38
|
+
"operator": {
|
39
|
+
"description": "Operator with limited access",
|
40
|
+
"allowed_servers": ["kubernetes_manager", "docker_manager", "monitor", "aiadm"],
|
41
|
+
"allowed_clients": ["admin", "super-admin", "operator"],
|
42
|
+
"permissions": ["read", "write"],
|
43
|
+
"priority": 50
|
44
|
+
},
|
45
|
+
"user": {
|
46
|
+
"description": "Regular user with basic access",
|
47
|
+
"allowed_servers": ["basic_commands", "info_commands"],
|
48
|
+
"allowed_clients": ["admin", "super-admin", "operator", "user"],
|
49
|
+
"permissions": ["read"],
|
50
|
+
"priority": 10
|
51
|
+
},
|
52
|
+
"guest": {
|
53
|
+
"description": "Guest user with minimal access",
|
54
|
+
"allowed_servers": ["help", "info"],
|
55
|
+
"allowed_clients": ["admin", "super-admin", "operator", "user", "guest"],
|
56
|
+
"permissions": ["read"],
|
57
|
+
"priority": 1
|
58
|
+
},
|
59
|
+
"system": {
|
60
|
+
"description": "System service with internal access",
|
61
|
+
"allowed_servers": ["*"],
|
62
|
+
"allowed_clients": ["admin", "super-admin", "system"],
|
63
|
+
"permissions": ["read", "write", "system"],
|
64
|
+
"priority": 150
|
65
|
+
}
|
66
|
+
},
|
67
|
+
"default_policy": {
|
68
|
+
"deny_by_default": true,
|
69
|
+
"require_role_match": true,
|
70
|
+
"case_sensitive": false,
|
71
|
+
"allow_wildcard": true
|
72
|
+
},
|
73
|
+
"role_hierarchy": {
|
74
|
+
"super-admin": ["admin", "user"],
|
75
|
+
"admin": ["operator", "user"],
|
76
|
+
"kubernetes_service": ["operator", "user"],
|
77
|
+
"ca_root": ["admin", "ca_intermediate", "kubernetes_service"],
|
78
|
+
"ca_intermediate": ["operator", "user"],
|
79
|
+
"operator": ["user"],
|
80
|
+
"user": ["guest"],
|
81
|
+
"system": ["admin", "user"]
|
82
|
+
},
|
83
|
+
"permissions": {
|
84
|
+
"read": {
|
85
|
+
"description": "Read access to data and commands",
|
86
|
+
"level": 1
|
87
|
+
},
|
88
|
+
"write": {
|
89
|
+
"description": "Write access to data and commands",
|
90
|
+
"level": 2
|
91
|
+
},
|
92
|
+
"delete": {
|
93
|
+
"description": "Delete access to data and commands",
|
94
|
+
"level": 3
|
95
|
+
},
|
96
|
+
"admin": {
|
97
|
+
"description": "Administrative access",
|
98
|
+
"level": 4
|
99
|
+
},
|
100
|
+
"system": {
|
101
|
+
"description": "System-level access",
|
102
|
+
"level": 5
|
103
|
+
}
|
104
|
+
},
|
105
|
+
"server_roles": {
|
106
|
+
"kubernetes_manager": {
|
107
|
+
"description": "Kubernetes management server",
|
108
|
+
"required_roles": ["admin", "operator", "kubernetes_service"],
|
109
|
+
"allowed_commands": ["k8s_*", "system_monitor"]
|
110
|
+
},
|
111
|
+
"kubernetes_api": {
|
112
|
+
"description": "Kubernetes API server",
|
113
|
+
"required_roles": ["kubernetes_service", "admin"],
|
114
|
+
"allowed_commands": ["k8s_api_*", "cluster_*"]
|
115
|
+
},
|
116
|
+
"cluster_monitor": {
|
117
|
+
"description": "Kubernetes cluster monitoring server",
|
118
|
+
"required_roles": ["kubernetes_service", "admin"],
|
119
|
+
"allowed_commands": ["monitor_*", "metrics_*"]
|
120
|
+
},
|
121
|
+
"k8s_operator": {
|
122
|
+
"description": "Kubernetes operator server",
|
123
|
+
"required_roles": ["kubernetes_service", "admin"],
|
124
|
+
"allowed_commands": ["operator_*", "crd_*"]
|
125
|
+
},
|
126
|
+
"certificate_manager": {
|
127
|
+
"description": "Certificate management server",
|
128
|
+
"required_roles": ["ca_root", "ca_intermediate", "admin"],
|
129
|
+
"allowed_commands": ["cert_*", "ca_*", "ssl_*"]
|
130
|
+
},
|
131
|
+
"ssl_manager": {
|
132
|
+
"description": "SSL/TLS management server",
|
133
|
+
"required_roles": ["ca_intermediate", "admin"],
|
134
|
+
"allowed_commands": ["ssl_*", "tls_*", "cert_*"]
|
135
|
+
},
|
136
|
+
"tls_manager": {
|
137
|
+
"description": "TLS management server",
|
138
|
+
"required_roles": ["ca_intermediate", "admin"],
|
139
|
+
"allowed_commands": ["tls_*", "mtls_*", "cert_*"]
|
140
|
+
},
|
141
|
+
"docker_manager": {
|
142
|
+
"description": "Docker management server",
|
143
|
+
"required_roles": ["admin", "operator"],
|
144
|
+
"allowed_commands": ["docker_*", "system_monitor"]
|
145
|
+
},
|
146
|
+
"aiadm": {
|
147
|
+
"description": "AI Admin server",
|
148
|
+
"required_roles": ["admin", "operator"],
|
149
|
+
"allowed_commands": ["*"]
|
150
|
+
},
|
151
|
+
"basic_commands": {
|
152
|
+
"description": "Basic command server",
|
153
|
+
"required_roles": ["user", "admin", "operator"],
|
154
|
+
"allowed_commands": ["help", "config", "health", "info"]
|
155
|
+
},
|
156
|
+
"help": {
|
157
|
+
"description": "Help server",
|
158
|
+
"required_roles": ["guest", "user", "admin", "operator"],
|
159
|
+
"allowed_commands": ["help"]
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|