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.
- 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 +65 -11
- 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/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 +1 -1
- {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/METADATA +1 -1
- mcp_proxy_adapter-3.0.1.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.1.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/licenses/LICENSE +0 -0
- {mcp_proxy_adapter-3.0.0.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,217 @@
|
|
1
|
+
"""
|
2
|
+
Unit tests for configuration module.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import json
|
6
|
+
import os
|
7
|
+
import tempfile
|
8
|
+
from typing import Generator
|
9
|
+
|
10
|
+
import pytest
|
11
|
+
|
12
|
+
from mcp_proxy_adapter.config import Config
|
13
|
+
|
14
|
+
|
15
|
+
@pytest.fixture
|
16
|
+
def temp_config_file() -> Generator[str, None, None]:
|
17
|
+
"""
|
18
|
+
Creates temporary configuration file for tests.
|
19
|
+
|
20
|
+
Returns:
|
21
|
+
Path to temporary configuration file.
|
22
|
+
"""
|
23
|
+
# Create temporary file
|
24
|
+
fd, path = tempfile.mkstemp(suffix=".json")
|
25
|
+
|
26
|
+
# Write test configuration
|
27
|
+
test_config = {
|
28
|
+
"server": {
|
29
|
+
"host": "127.0.0.1",
|
30
|
+
"port": 8000
|
31
|
+
},
|
32
|
+
"logging": {
|
33
|
+
"level": "DEBUG",
|
34
|
+
"file": "test.log"
|
35
|
+
},
|
36
|
+
"test_section": {
|
37
|
+
"test_key": "test_value",
|
38
|
+
"nested": {
|
39
|
+
"key1": "value1",
|
40
|
+
"key2": 42
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
with os.fdopen(fd, "w") as f:
|
46
|
+
json.dump(test_config, f)
|
47
|
+
|
48
|
+
yield path
|
49
|
+
|
50
|
+
# Remove temporary file after tests
|
51
|
+
os.unlink(path)
|
52
|
+
|
53
|
+
|
54
|
+
@pytest.mark.unit
|
55
|
+
def test_config_load_from_file(temp_config_file: str):
|
56
|
+
"""
|
57
|
+
Test loading configuration from file.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
temp_config_file: Path to temporary configuration file.
|
61
|
+
"""
|
62
|
+
config = Config(temp_config_file)
|
63
|
+
|
64
|
+
# Check loaded values
|
65
|
+
assert config.get("server.host") == "127.0.0.1"
|
66
|
+
assert config.get("server.port") == 8000
|
67
|
+
assert config.get("logging.level") == "DEBUG"
|
68
|
+
assert config.get("logging.file") == "test.log"
|
69
|
+
assert config.get("test_section.test_key") == "test_value"
|
70
|
+
|
71
|
+
|
72
|
+
@pytest.mark.unit
|
73
|
+
def test_config_get_nested_values(temp_config_file: str):
|
74
|
+
"""
|
75
|
+
Test getting nested values from configuration.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
temp_config_file: Path to temporary configuration file.
|
79
|
+
"""
|
80
|
+
config = Config(temp_config_file)
|
81
|
+
|
82
|
+
# Get nested values
|
83
|
+
assert config.get("test_section.nested.key1") == "value1"
|
84
|
+
assert config.get("test_section.nested.key2") == 42
|
85
|
+
|
86
|
+
|
87
|
+
@pytest.mark.unit
|
88
|
+
def test_config_get_with_default(temp_config_file: str):
|
89
|
+
"""
|
90
|
+
Test getting configuration values with default.
|
91
|
+
|
92
|
+
Args:
|
93
|
+
temp_config_file: Path to temporary configuration file.
|
94
|
+
"""
|
95
|
+
config = Config(temp_config_file)
|
96
|
+
|
97
|
+
# Get non-existent values with defaults
|
98
|
+
assert config.get("non_existent", default="default") == "default"
|
99
|
+
assert config.get("server.non_existent", default=123) == 123
|
100
|
+
assert config.get("test_section.nested.non_existent", default=False) is False
|
101
|
+
|
102
|
+
|
103
|
+
@pytest.mark.unit
|
104
|
+
def test_config_get_without_default(temp_config_file: str):
|
105
|
+
"""
|
106
|
+
Test getting non-existent configuration values without default.
|
107
|
+
|
108
|
+
Args:
|
109
|
+
temp_config_file: Path to temporary configuration file.
|
110
|
+
"""
|
111
|
+
config = Config(temp_config_file)
|
112
|
+
|
113
|
+
# Get non-existent values without defaults
|
114
|
+
assert config.get("non_existent") is None
|
115
|
+
assert config.get("server.non_existent") is None
|
116
|
+
assert config.get("test_section.nested.non_existent") is None
|
117
|
+
|
118
|
+
|
119
|
+
@pytest.mark.unit
|
120
|
+
def test_config_set_value(temp_config_file: str):
|
121
|
+
"""
|
122
|
+
Test setting configuration values.
|
123
|
+
|
124
|
+
Args:
|
125
|
+
temp_config_file: Path to temporary configuration file.
|
126
|
+
"""
|
127
|
+
config = Config(temp_config_file)
|
128
|
+
|
129
|
+
# Set values
|
130
|
+
config.set("server.host", "localhost")
|
131
|
+
config.set("logging.level", "INFO")
|
132
|
+
config.set("new_section.new_key", "new_value")
|
133
|
+
|
134
|
+
# Check set values
|
135
|
+
assert config.get("server.host") == "localhost"
|
136
|
+
assert config.get("logging.level") == "INFO"
|
137
|
+
assert config.get("new_section.new_key") == "new_value"
|
138
|
+
|
139
|
+
|
140
|
+
@pytest.mark.unit
|
141
|
+
def test_config_save_and_load(temp_config_file: str):
|
142
|
+
"""
|
143
|
+
Test saving and loading configuration.
|
144
|
+
|
145
|
+
Args:
|
146
|
+
temp_config_file: Path to temporary configuration file.
|
147
|
+
"""
|
148
|
+
# Create and modify configuration
|
149
|
+
config1 = Config(temp_config_file)
|
150
|
+
config1.set("server.host", "localhost")
|
151
|
+
config1.set("new_section.new_key", "new_value")
|
152
|
+
|
153
|
+
# Save configuration
|
154
|
+
config1.save()
|
155
|
+
|
156
|
+
# Load configuration again
|
157
|
+
config2 = Config(temp_config_file)
|
158
|
+
|
159
|
+
# Check values
|
160
|
+
assert config2.get("server.host") == "localhost"
|
161
|
+
assert config2.get("new_section.new_key") == "new_value"
|
162
|
+
|
163
|
+
|
164
|
+
@pytest.mark.unit
|
165
|
+
def test_config_load_updated_file(temp_config_file: str):
|
166
|
+
"""
|
167
|
+
Test loading updated configuration from file.
|
168
|
+
|
169
|
+
Args:
|
170
|
+
temp_config_file: Path to temporary configuration file.
|
171
|
+
"""
|
172
|
+
# Load configuration
|
173
|
+
config = Config(temp_config_file)
|
174
|
+
original_host = config.get("server.host")
|
175
|
+
|
176
|
+
# Modify file directly
|
177
|
+
with open(temp_config_file, "r+") as f:
|
178
|
+
data = json.load(f)
|
179
|
+
data["server"]["host"] = "new_host"
|
180
|
+
f.seek(0)
|
181
|
+
f.truncate()
|
182
|
+
json.dump(data, f)
|
183
|
+
|
184
|
+
# Create new config instance to load updated file
|
185
|
+
updated_config = Config(temp_config_file)
|
186
|
+
|
187
|
+
# Check that value was updated
|
188
|
+
assert updated_config.get("server.host") == "new_host"
|
189
|
+
assert updated_config.get("server.host") != original_host
|
190
|
+
|
191
|
+
|
192
|
+
@pytest.mark.unit
|
193
|
+
def test_config_access_nested_sections(temp_config_file: str):
|
194
|
+
"""
|
195
|
+
Test accessing nested configuration sections directly.
|
196
|
+
|
197
|
+
Args:
|
198
|
+
temp_config_file: Path to temporary configuration file.
|
199
|
+
"""
|
200
|
+
config = Config(temp_config_file)
|
201
|
+
|
202
|
+
# Get parent key then access nested keys
|
203
|
+
server = config.get("server")
|
204
|
+
logging = config.get("logging")
|
205
|
+
test_section = config.get("test_section")
|
206
|
+
|
207
|
+
# Check sections
|
208
|
+
assert isinstance(server, dict)
|
209
|
+
assert isinstance(logging, dict)
|
210
|
+
assert isinstance(test_section, dict)
|
211
|
+
|
212
|
+
assert server["host"] == "127.0.0.1"
|
213
|
+
assert server["port"] == 8000
|
214
|
+
assert logging["level"] == "DEBUG"
|
215
|
+
assert logging["file"] == "test.log"
|
216
|
+
assert test_section["test_key"] == "test_value"
|
217
|
+
assert test_section["nested"]["key1"] == "value1"
|
mcp_proxy_adapter/version.py
CHANGED
@@ -0,0 +1,109 @@
|
|
1
|
+
examples/__init__.py,sha256=sLYNpeoiE-X5q7fmJb7NFMmhiIn0543mgJj16q1qmk0,593
|
2
|
+
examples/server.py,sha256=gnRTE_k7C0A255dLyaJWyA4YU0H6Elc7osr_JQvsQhQ,2286
|
3
|
+
examples/simple_server.py,sha256=Bkczmz5Qs473xJ0_AJjBpqWT-oWctwED98A067z05zQ,3768
|
4
|
+
examples/test_server.py,sha256=cKWJ4tlHqZsRKyeuXbZ1dQ7TU9riJWcDan__wK7YH_Y,3729
|
5
|
+
examples/tool_description_example.py,sha256=blamrx_1oHCG4NnvIiYnQxphAEDqb7-TALPALJFj51s,3280
|
6
|
+
examples/anti_patterns/README.md,sha256=1-Hby6Wf3kAC0XOV_jOvuHL-kmTypWOUfE_rEU3Knu8,2045
|
7
|
+
examples/anti_patterns/__init__.py,sha256=xbgoTIMM2LNt4P8h0jTaenUxXkA_l9I7JL_9d4BhoDU,261
|
8
|
+
examples/anti_patterns/bad_design/README.md,sha256=SJDMXZfvNMajN0JyvPBm5GtzxyiZZdtMfHslW3-LOII,2422
|
9
|
+
examples/anti_patterns/bad_design/global_state.py,sha256=UnpMCWDfl-DaZSPhWl8C9fGifXkG_sYKhjx3_HvTiSI,5161
|
10
|
+
examples/anti_patterns/bad_design/monolithic_command.py,sha256=gdp1Ok4h4dKto7nfJmhjoWTtjdCfwI-MtcKpn6il7Yo,8815
|
11
|
+
examples/basic_example/README.md,sha256=H2Q5D8XcINpHZoX9fS0UDBFZyd3shNa5PEd6EOckHQQ,8274
|
12
|
+
examples/basic_example/__init__.py,sha256=SXYCM5mPlVpEMdahhukXSYVepNiPNddhgypwAlhJjDU,191
|
13
|
+
examples/basic_example/config.json,sha256=xln79S29iS-borOL61lR3Hw4V5vg83FMs-Ke3j4YqZQ,425
|
14
|
+
examples/basic_example/server.py,sha256=0qoV59ofWBwCGxQX3jefr5WSyvZsEY0X18USh7x-s2s,4900
|
15
|
+
examples/basic_example/commands/__init__.py,sha256=jD5tBWpkxH1Yk9kBHS_V3bBIMxwqqY4skr7RGuRru9s,115
|
16
|
+
examples/basic_example/commands/echo_command.py,sha256=EoXMHEf5ouKjvxvZAEiNH6hqyD6ktyyEDWYP-6Oa2D4,2128
|
17
|
+
examples/basic_example/commands/math_command.py,sha256=apJuU5EXlR965rGmAd2h8zcPWgLUSROtPeZ7Ml0H6nw,4423
|
18
|
+
examples/basic_example/commands/time_command.py,sha256=REw-8RCgq9iVUdQxnIFPmeYO_9_6-7QVLzLKLGq0Lb0,4345
|
19
|
+
examples/basic_example/docs/EN/README.md,sha256=grOp0Adr3h9m-XZLCgLO6haBdUOjc4_VosirNaLl7dU,4637
|
20
|
+
examples/basic_example/docs/RU/README.md,sha256=8jBObIj_3-eDmFt35ufIRw6mm41FyUXJD7olHmKS2QM,6736
|
21
|
+
examples/basic_example/tests/conftest.py,sha256=6e85QRE50P9PMV1RXXVgtBQxy49hVLbevZ6dHFBrxRU,5917
|
22
|
+
examples/commands/echo_command.py,sha256=7RuUZfP0YlKl9gks02NiuiYEiiNPa_8lk9CAZmzijyo,1569
|
23
|
+
examples/commands/echo_result.py,sha256=q5IUEeFoi4PunzOhYD0zju2ZwETdGl35yj4DVXZfX68,1635
|
24
|
+
examples/commands/get_date_command.py,sha256=ePQzZCV-n3tLf4IYv6Gn75t0AXXplXtikCDmrIMD2Q4,2537
|
25
|
+
examples/commands/new_uuid4_command.py,sha256=lJQiPuVHtKCnOEUQukji6dwe0VOkddJ7sZXZ7XUsY6Y,2240
|
26
|
+
examples/complete_example/Dockerfile,sha256=MpwyUpA2wMeLtEVQ2ay98z-l8EX5aEFvwUSxZCCxg64,499
|
27
|
+
examples/complete_example/README.md,sha256=EupIC8DhC7dVsObbXjuERpwheVzfLR2i0y3LzCRHLYs,2784
|
28
|
+
examples/complete_example/__init__.py,sha256=JQDNMNOrQAvbQyEV7tV3XrVKBxZRYy3ODMCVyOxU404,216
|
29
|
+
examples/complete_example/config.json,sha256=KbfZnu4SMYH6B7ENQaZ_sZXrWdkmCdMcWgy47nAHh_Q,814
|
30
|
+
examples/complete_example/docker-compose.yml,sha256=kBXjXFeswZCZ4-UhI0vC0OMR_nMRRoDt3PltCi-RGb8,924
|
31
|
+
examples/complete_example/requirements.txt,sha256=QHeMbXMHgkISmFoXfO09kiaXAMkg0nNBdCfwThKiHDc,403
|
32
|
+
examples/complete_example/server.py,sha256=JzJPIHI6EJFMRqYw-ZhxIRkYGH-Mdm2UdGiizt04Q0M,4146
|
33
|
+
examples/complete_example/commands/__init__.py,sha256=cZDiwz3nLaeSCwR4oK7xlGgVsXt2WyAlIEMWCxSJPAE,121
|
34
|
+
examples/complete_example/commands/system_command.py,sha256=CwcBRWMODG7Ynr9Syaildu3APuuUdJ_yvQOggAAidg8,10717
|
35
|
+
examples/complete_example/configs/config.dev.yaml,sha256=ASIwU8xzB-kinAsLGghv8-LCER1SUC1ed6K8BktOYPQ,1282
|
36
|
+
examples/complete_example/configs/config.docker.yaml,sha256=DZWxauz5fcaiVFaphvf7zpvLI3oXjUUiXdX_bGlcBds,1389
|
37
|
+
examples/minimal_example/README.md,sha256=VFKjDgpNjFowYNLD3sHHGsc1CVhCm30BWPGBqpLFKAc,2569
|
38
|
+
examples/minimal_example/__init__.py,sha256=EloOqdgVLp7YA2DJOWMw0ZxFbVUCH2LqvZVq5RSfSbg,165
|
39
|
+
examples/minimal_example/config.json,sha256=FSL0q_dAyGHJXp37bLesUvvNgrCiFXkQ8_P7nuUhIcQ,250
|
40
|
+
examples/minimal_example/main.py,sha256=5JAoUz_Gy56kcRTxlpuj27PThU6o6R-lKiySIpwsR7s,4770
|
41
|
+
examples/minimal_example/simple_server.py,sha256=IrS32z5G3Z8Ck7pcqwPmrMMA157sFtHM7brP465q54Y,5372
|
42
|
+
examples/minimal_example/tests/conftest.py,sha256=8kRuZws9twR6D4WX9OoSjtK4NwSCAvENPgp9uX3Dg58,4165
|
43
|
+
examples/minimal_example/tests/test_hello_command.py,sha256=C48o7Hh_gy2NlLqb2KKm2HX37df8eIop0IQfOxWPVS0,3485
|
44
|
+
examples/minimal_example/tests/test_integration.py,sha256=mW9LEXX5yOCxP3uIpGMiTEMci7DE8PDDCiE8rKJn4ds,6213
|
45
|
+
mcp_proxy_adapter/__init__.py,sha256=B7m1YWyv_Wb87-Q-JqVpHQgwajnfIgDyZ_iIxzdTbBY,1021
|
46
|
+
mcp_proxy_adapter/config.py,sha256=MjgZAld6TiD0F5oCyEaJhYhfEXVZxc5G5ke2SLKCV9A,5748
|
47
|
+
mcp_proxy_adapter/custom_openapi.py,sha256=EFEjeQ3DudgTfb4870PWkF1upWM5RaY1PY9jxTSOwU8,4142
|
48
|
+
mcp_proxy_adapter/openapi.py,sha256=jyl5EPXcFhzFKEEMXxHeqF1U-SsYvtdlaKGU2QrekpU,13889
|
49
|
+
mcp_proxy_adapter/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
|
+
mcp_proxy_adapter/version.py,sha256=dJk-xMDB6JeaL5chSa3I4Y6cpYWyK2dbuJHiHLtX4Og,71
|
51
|
+
mcp_proxy_adapter/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
52
|
+
mcp_proxy_adapter/api/app.py,sha256=q3yYsNEBFXYr2TOJFxfh6bbF53NkmmgfzSFOtVq7xdc,14353
|
53
|
+
mcp_proxy_adapter/api/handlers.py,sha256=4oAkc-szU3tggkLehqvTW2P5c3HTLIiqXQMwCY0ua2Q,7043
|
54
|
+
mcp_proxy_adapter/api/schemas.py,sha256=xOmiSwHaapY6myEFnLu7o-LWVPM7vwmLYZXFo2c6NfE,12381
|
55
|
+
mcp_proxy_adapter/api/tool_integration.py,sha256=4nnE9I4XIHrsE5vN-I4e5xYJhHrHBDM-vMHT5lD9HWo,10137
|
56
|
+
mcp_proxy_adapter/api/tools.py,sha256=nSDXD4rGlFV_NlB91Y0x3N8WeWvWZ76B32-s-VAFARw,8084
|
57
|
+
mcp_proxy_adapter/api/middleware/__init__.py,sha256=RpaA5hbZ7XIjKaQK0PJpZNqc9tFISe5w7ZmqNgwC6FE,1556
|
58
|
+
mcp_proxy_adapter/api/middleware/auth.py,sha256=bic-ez4o4xh74ZczLXSNafrk_m2qk82GF9MHmfDpf9w,4891
|
59
|
+
mcp_proxy_adapter/api/middleware/base.py,sha256=aMV9YPLHkUnJECuQWYbnlEGaj6xUJFHZR_hJb0OKvu8,2282
|
60
|
+
mcp_proxy_adapter/api/middleware/error_handling.py,sha256=ShguFRn9GBBprevKO7n77ENw4PwYhvBNFu4ptLyjxYQ,6876
|
61
|
+
mcp_proxy_adapter/api/middleware/logging.py,sha256=wGtw4BqKMLgn5zqYd84DnVPtO3evfx2X-TxOCyAmysM,3679
|
62
|
+
mcp_proxy_adapter/api/middleware/performance.py,sha256=dHBxTF43LEGXMKHMH3A8ybKmwAWURd_zswqq_oC4xbw,2454
|
63
|
+
mcp_proxy_adapter/api/middleware/rate_limit.py,sha256=DIv_-ZUVmL-jEo_A5BlfnasZf25zT84AiIJDUUnXkpM,5041
|
64
|
+
mcp_proxy_adapter/commands/__init__.py,sha256=cbds-RqRNyF-BM1PMa_j6OfyTENXzh54Z1aI2b3XpCU,475
|
65
|
+
mcp_proxy_adapter/commands/base.py,sha256=NF7Xvssc6T3rb0s-LcDzjxG4IisNR0911EQpc-LbDyk,10670
|
66
|
+
mcp_proxy_adapter/commands/command_registry.py,sha256=fNPsD1fQGDCp6qMnG3uMa-bDkPTAEw-GgFfoW0Sfwd8,8015
|
67
|
+
mcp_proxy_adapter/commands/config_command.py,sha256=-Z6BGaEQTf859l56zZpHYBeZFeIVdpMYybDrd7LOPIg,3553
|
68
|
+
mcp_proxy_adapter/commands/health_command.py,sha256=_tzxHwB_8vo53VBC6HnBv5fSfZL1pEuwlbrCcy_K78c,4087
|
69
|
+
mcp_proxy_adapter/commands/help_command.py,sha256=UguKpvnmyW6qXZZyzdcJSVqKzLYi-AvaXo_UKyLR8js,6836
|
70
|
+
mcp_proxy_adapter/commands/result.py,sha256=2WjftiAuhlyzOKmPJlQHo_b08ZCzWoK7cquUHFLVE-E,5534
|
71
|
+
mcp_proxy_adapter/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
72
|
+
mcp_proxy_adapter/core/errors.py,sha256=s34OxiIR4NCJu_pYSigKXqrIvRjUUK2OWw0X4dpDjIA,5151
|
73
|
+
mcp_proxy_adapter/core/logging.py,sha256=bvvT1ouSyyT1B9za506W-ASW4AoxYnyU_OeGgSgOFsQ,7102
|
74
|
+
mcp_proxy_adapter/core/utils.py,sha256=WJZYNxOXLCPhTF0OH0bzMFYWW6SWwo6XaWG-S5za7u0,3249
|
75
|
+
mcp_proxy_adapter/schemas/base_schema.json,sha256=v9G9cGMd4dRhCZsOQ_FMqOi5VFyVbI6Cf3fyIvOT9dc,2881
|
76
|
+
mcp_proxy_adapter/schemas/openapi_schema.json,sha256=C3yLkwmDsvnLW9B5gnKKdBGl4zxkeU-rEmjTrNVsQU0,8405
|
77
|
+
mcp_proxy_adapter/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
78
|
+
mcp_proxy_adapter/tests/conftest.py,sha256=VBA2wLeYfp9XAGSq4c489PVBIqMGAJiQPrT0k3kyzXw,2999
|
79
|
+
mcp_proxy_adapter/tests/test_api_endpoints.py,sha256=ePtWCf0szD1JeY9WdHAhcKnuOzoSCpUcqZ_2DVhlC-A,10280
|
80
|
+
mcp_proxy_adapter/tests/test_api_handlers.py,sha256=LeHO0o6eCxan6mt_8ZkUwSbeY7qYfoYMJ-bT_sSgdxc,11011
|
81
|
+
mcp_proxy_adapter/tests/test_base_command.py,sha256=Oa-W3Z_758hLobsUcWMdZU2YxTueLusrzzRY1ZwSRY4,3778
|
82
|
+
mcp_proxy_adapter/tests/test_batch_requests.py,sha256=9-gvhPq48AcEwGlhwgn3DWNhpleLA0f4luZNYMrqlXY,4103
|
83
|
+
mcp_proxy_adapter/tests/test_command_registry.py,sha256=o5HHxlQ-D2ML0ufJK-lXQv-qYWccvalOHGVvpc8QFTU,6285
|
84
|
+
mcp_proxy_adapter/tests/test_config.py,sha256=i4YbFhB3WI1wWKCxkG6l-UpFv2LAbhh4hmGipmYG1d0,3928
|
85
|
+
mcp_proxy_adapter/tests/test_utils.py,sha256=K8DqdWDAV-cXjjeykehHpG5phfq5ydu2HLJzaAL282Y,1653
|
86
|
+
mcp_proxy_adapter/tests/api/__init__.py,sha256=QzjeBIhrRLqfUKYmxVSCbMOoni5MAXgyAx9HxxB6JRs,27
|
87
|
+
mcp_proxy_adapter/tests/api/test_cmd_endpoint.py,sha256=RFg_N7Ut1l_pncUPMaqVg85XV4KTpVe03yI_VA0Z47o,3843
|
88
|
+
mcp_proxy_adapter/tests/api/test_middleware.py,sha256=A_-rpW0Kifg4SgjV3NxjQhOhFUSbnUWJjVJAAQWjEeQ,12063
|
89
|
+
mcp_proxy_adapter/tests/commands/__init__.py,sha256=DZxhtyr__AleyXN1s8Ef887tK5nsoHKfW4QXyzLaP0E,36
|
90
|
+
mcp_proxy_adapter/tests/commands/test_config_command.py,sha256=ud0Y57xUhFiyrUKDyA0eBZ8IOKiGDpioijtwY-detC4,6522
|
91
|
+
mcp_proxy_adapter/tests/commands/test_echo_command.py,sha256=c2dmqfx3ZfvDedy5vuxArFv7iHsReepMmD2Lchg4l3E,3437
|
92
|
+
mcp_proxy_adapter/tests/commands/test_help_command.py,sha256=OJCZMS0BqUUNNSecipd3dOFokUATiET3gpCoVAxPXPA,4116
|
93
|
+
mcp_proxy_adapter/tests/functional/__init__.py,sha256=muVNR6LD5o7DsDaLrbLTFsavUNcnyM608-mr-dqzgDU,59
|
94
|
+
mcp_proxy_adapter/tests/functional/test_api.py,sha256=Vsn4IsZ5uEa7g4G5IIyyhvdx6Xa0FuWSPd7XVxVMTP8,6554
|
95
|
+
mcp_proxy_adapter/tests/integration/__init__.py,sha256=JZpeNG1PBRZ3k5zfq6NH3GyzDc1Yx1ZUgwi6eLBxs1o,60
|
96
|
+
mcp_proxy_adapter/tests/integration/test_cmd_integration.py,sha256=OqBxh52WPijKaRrIHA54QDJQLBz_nwlCywF9k5jxa_Y,3430
|
97
|
+
mcp_proxy_adapter/tests/integration/test_integration.py,sha256=Rf8GTxdZOvZzrtgqWN2fp-36qUU5rpHdV9zhN1JxNw8,6619
|
98
|
+
mcp_proxy_adapter/tests/performance/__init__.py,sha256=2kHf6g4LmYnFuV4EALXzo7Qk9vHGA9DXZFt7nORRFjM,60
|
99
|
+
mcp_proxy_adapter/tests/performance/test_performance.py,sha256=Djrnu-SsXRrc_Prj1Aw8OoPzPUwHJds-Itk3aX6o01w,5730
|
100
|
+
mcp_proxy_adapter/tests/stubs/__init__.py,sha256=qJ_gqvLdt68rAfLOeJpjVcLWyWdhEg6RkKheyV2yjJs,178
|
101
|
+
mcp_proxy_adapter/tests/stubs/echo_command.py,sha256=Y7SA4IB5Lo_ncn78SDm9iRZvJSKy2pXi2nBQjIUPrvg,2620
|
102
|
+
mcp_proxy_adapter/tests/unit/__init__.py,sha256=RS-5UoSCcLKtr2jrAaZw_NG9MquA6BZmxq-P6cTw9ok,53
|
103
|
+
mcp_proxy_adapter/tests/unit/test_base_command.py,sha256=ldDXQYk2eijbTgZioSBAhHzSAa_SuBKYqCutCEzUYTE,3924
|
104
|
+
mcp_proxy_adapter/tests/unit/test_config.py,sha256=SZ62LXFOv_fsV0fmSIBdHWvapEyexKrioFRQo0I4pkg,5900
|
105
|
+
mcp_proxy_adapter-3.0.1.dist-info/licenses/LICENSE,sha256=OkApFEwdgMCt_mbvUI-eIwKMSTe38K3XnU2DT5ub-wI,1072
|
106
|
+
mcp_proxy_adapter-3.0.1.dist-info/METADATA,sha256=IQfUDUcgTOvLRjUNzcEwp6knWzfaJxYxhS9DEYblork,7537
|
107
|
+
mcp_proxy_adapter-3.0.1.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
108
|
+
mcp_proxy_adapter-3.0.1.dist-info/top_level.txt,sha256=kxq3OC7vBtsFdy9dDVse4cOl-SV_QlvcTeSkuw_jw3I,27
|
109
|
+
mcp_proxy_adapter-3.0.1.dist-info/RECORD,,
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# Configuration for basic MCP Microservice example
|
2
|
-
|
3
|
-
# Server settings
|
4
|
-
server:
|
5
|
-
host: "localhost" # Host to bind server
|
6
|
-
port: 8000 # Port to bind server
|
7
|
-
|
8
|
-
# Logging settings
|
9
|
-
logging:
|
10
|
-
level: "INFO" # Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
11
|
-
file: "logs/basic_example.log" # Log file path
|
12
|
-
rotation:
|
13
|
-
type: "size" # Log rotation type (size, time)
|
14
|
-
max_bytes: 10485760 # Maximum log file size (10 MB)
|
15
|
-
backup_count: 5 # Number of backup files
|
16
|
-
|
17
|
-
# Command discovery settings
|
18
|
-
discovery:
|
19
|
-
enabled: true
|
20
|
-
package: "commands" # Package to discover commands
|
examples/basic_example/main.py
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Пример запуска сервера mcp-proxy-adapter с базовыми командами.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import os
|
6
|
-
import sys
|
7
|
-
import uvicorn
|
8
|
-
import logging
|
9
|
-
|
10
|
-
from mcp_proxy_adapter.api.app import create_app
|
11
|
-
from mcp_proxy_adapter.config import config
|
12
|
-
from mcp_proxy_adapter.core.logging import setup_logging
|
13
|
-
|
14
|
-
# Импортируем команды из примера
|
15
|
-
from commands.echo_command import EchoCommand
|
16
|
-
from commands.math_command import MathCommand
|
17
|
-
|
18
|
-
def main():
|
19
|
-
"""
|
20
|
-
Основная функция запуска сервера.
|
21
|
-
"""
|
22
|
-
try:
|
23
|
-
# Настраиваем логирование
|
24
|
-
log_level = config.get("logging.level", "INFO")
|
25
|
-
setup_logging(log_level)
|
26
|
-
|
27
|
-
# Получаем настройки сервера
|
28
|
-
host = config.get("server.host", "0.0.0.0")
|
29
|
-
port = int(config.get("server.port", 8000))
|
30
|
-
|
31
|
-
# Регистрируем команды
|
32
|
-
app = create_app()
|
33
|
-
|
34
|
-
# Запускаем сервер
|
35
|
-
print(f"Запуск сервера на http://{host}:{port}")
|
36
|
-
print(f"Документация доступна по адресу: http://{host}:{port}/docs")
|
37
|
-
|
38
|
-
uvicorn.run(
|
39
|
-
app,
|
40
|
-
host=host,
|
41
|
-
port=port,
|
42
|
-
reload=True if os.environ.get("DEBUG") else False,
|
43
|
-
log_level=log_level.lower()
|
44
|
-
)
|
45
|
-
except Exception as e:
|
46
|
-
print(f"Ошибка при запуске приложения: {e}")
|
47
|
-
sys.exit(1)
|
48
|
-
|
49
|
-
if __name__ == "__main__":
|
50
|
-
main()
|
@@ -1,67 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Main application module.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import os
|
6
|
-
import sys
|
7
|
-
import uvicorn
|
8
|
-
import logging
|
9
|
-
|
10
|
-
from mcp_proxy_adapter.api.app import app
|
11
|
-
from mcp_proxy_adapter.config import config
|
12
|
-
from mcp_proxy_adapter.core.logging import logger, setup_logging
|
13
|
-
|
14
|
-
|
15
|
-
def main():
|
16
|
-
"""
|
17
|
-
Main function to run the application.
|
18
|
-
"""
|
19
|
-
# Убедимся что логирование настроено
|
20
|
-
logger.info("Initializing logging configuration")
|
21
|
-
|
22
|
-
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")
|
27
|
-
|
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
|
48
|
-
host = config.get("server.host", "0.0.0.0")
|
49
|
-
port = config.get("server.port", 8000)
|
50
|
-
|
51
|
-
logger.info(f"Starting server on {host}:{port}")
|
52
|
-
|
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
|
-
)
|
61
|
-
except Exception as e:
|
62
|
-
logger.exception(f"Error during application startup: {e}")
|
63
|
-
sys.exit(1)
|
64
|
-
|
65
|
-
|
66
|
-
if __name__ == "__main__":
|
67
|
-
main()
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# Minimal Example Configuration
|
2
|
-
|
3
|
-
service:
|
4
|
-
name: "Minimal Example"
|
5
|
-
version: "1.0.0"
|
6
|
-
|
7
|
-
server:
|
8
|
-
host: "0.0.0.0"
|
9
|
-
port: 8000
|
10
|
-
debug: true
|
11
|
-
log_level: "info"
|
12
|
-
|
13
|
-
# Uncomment and configure this section if you need authentication
|
14
|
-
# auth:
|
15
|
-
# enabled: false
|
16
|
-
# secret_key: ""
|
17
|
-
# token_expiration: 3600 # seconds
|
18
|
-
|
19
|
-
# Настройки логирования
|
20
|
-
logging:
|
21
|
-
level: "INFO" # Уровень логирования (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
22
|
-
file: "logs/minimal_example.log" # Файл для записи логов
|
23
|
-
rotation:
|
24
|
-
type: "size" # Тип ротации логов (size, time)
|
25
|
-
max_bytes: 10485760 # Максимальный размер файла лога (10 МБ)
|
26
|
-
backup_count: 5 # Количество резервных копий
|
mcp_proxy_adapter/framework.py
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Framework module for creating microservices.
|
3
|
-
"""
|
4
|
-
|
5
|
-
import os
|
6
|
-
import uvicorn
|
7
|
-
from typing import Any, Callable, Dict, List, Optional, Type, Union
|
8
|
-
|
9
|
-
from fastapi import FastAPI
|
10
|
-
|
11
|
-
from mcp_proxy_adapter.api.app import create_app
|
12
|
-
from mcp_proxy_adapter.commands.base import Command
|
13
|
-
from mcp_proxy_adapter.commands.command_registry import registry
|
14
|
-
from mcp_proxy_adapter.config import config
|
15
|
-
from mcp_proxy_adapter.core.logging import logger, setup_logging
|
16
|
-
|
17
|
-
|
18
|
-
class MicroService:
|
19
|
-
"""
|
20
|
-
Main class for creating and managing microservices.
|
21
|
-
"""
|
22
|
-
|
23
|
-
def __init__(
|
24
|
-
self,
|
25
|
-
title: str = "MicroService",
|
26
|
-
description: str = "JSON-RPC microservice",
|
27
|
-
version: str = "1.0.0",
|
28
|
-
config_path: Optional[str] = None,
|
29
|
-
log_level: str = "INFO",
|
30
|
-
):
|
31
|
-
"""
|
32
|
-
Initialize microservice.
|
33
|
-
|
34
|
-
Args:
|
35
|
-
title: Service title (displayed in docs)
|
36
|
-
description: Service description (displayed in docs)
|
37
|
-
version: Service version
|
38
|
-
config_path: Path to configuration file
|
39
|
-
log_level: Logging level
|
40
|
-
"""
|
41
|
-
# Set configuration
|
42
|
-
if config_path and os.path.exists(config_path):
|
43
|
-
config.load_from_file(config_path)
|
44
|
-
|
45
|
-
# Set logging
|
46
|
-
setup_logging(log_level)
|
47
|
-
|
48
|
-
# Create FastAPI app
|
49
|
-
self.app = create_app()
|
50
|
-
self.app.title = title
|
51
|
-
self.app.description = description
|
52
|
-
self.app.version = version
|
53
|
-
|
54
|
-
logger.info(f"MicroService '{title}' v{version} initialized")
|
55
|
-
|
56
|
-
def register_command(self, command_class: Type[Command]) -> None:
|
57
|
-
"""
|
58
|
-
Register command in the service.
|
59
|
-
|
60
|
-
Args:
|
61
|
-
command_class: Command class to register
|
62
|
-
"""
|
63
|
-
registry.register(command_class)
|
64
|
-
logger.info(f"Command '{command_class.name if hasattr(command_class, 'name') else command_class.__name__}' registered")
|
65
|
-
|
66
|
-
def discover_commands(self, package_path: str) -> None:
|
67
|
-
"""
|
68
|
-
Automatically discover and register commands in package.
|
69
|
-
|
70
|
-
Args:
|
71
|
-
package_path: Path to package with commands
|
72
|
-
"""
|
73
|
-
registry.discover_commands(package_path)
|
74
|
-
logger.info(f"Commands discovered in package '{package_path}'")
|
75
|
-
|
76
|
-
def run(
|
77
|
-
self,
|
78
|
-
host: str = "0.0.0.0",
|
79
|
-
port: int = 8000,
|
80
|
-
reload: bool = False,
|
81
|
-
workers: int = 1,
|
82
|
-
) -> None:
|
83
|
-
"""
|
84
|
-
Run microservice.
|
85
|
-
|
86
|
-
Args:
|
87
|
-
host: Host to bind server
|
88
|
-
port: Port to bind server
|
89
|
-
reload: Enable auto-reload on code changes
|
90
|
-
workers: Number of worker processes
|
91
|
-
"""
|
92
|
-
logger.info(f"Starting microservice on {host}:{port}")
|
93
|
-
uvicorn.run(
|
94
|
-
self.app,
|
95
|
-
host=host,
|
96
|
-
port=port,
|
97
|
-
reload=reload,
|
98
|
-
workers=workers,
|
99
|
-
log_level=config.get("logging.level", "info").lower()
|
100
|
-
)
|
101
|
-
|
102
|
-
def get_app(self) -> FastAPI:
|
103
|
-
"""
|
104
|
-
Get FastAPI application instance.
|
105
|
-
|
106
|
-
Returns:
|
107
|
-
FastAPI application
|
108
|
-
"""
|
109
|
-
return self.app
|