mcp-proxy-adapter 3.1.6__py3-none-any.whl → 4.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/api/app.py +65 -27
- mcp_proxy_adapter/api/handlers.py +1 -1
- mcp_proxy_adapter/api/middleware/error_handling.py +11 -10
- mcp_proxy_adapter/api/tool_integration.py +5 -2
- mcp_proxy_adapter/api/tools.py +3 -3
- mcp_proxy_adapter/commands/base.py +19 -1
- mcp_proxy_adapter/commands/command_registry.py +243 -6
- mcp_proxy_adapter/commands/hooks.py +260 -0
- mcp_proxy_adapter/commands/reload_command.py +211 -0
- mcp_proxy_adapter/commands/reload_settings_command.py +125 -0
- mcp_proxy_adapter/commands/settings_command.py +189 -0
- mcp_proxy_adapter/config.py +16 -1
- mcp_proxy_adapter/core/__init__.py +44 -0
- mcp_proxy_adapter/core/logging.py +87 -34
- mcp_proxy_adapter/core/settings.py +376 -0
- mcp_proxy_adapter/core/utils.py +2 -2
- mcp_proxy_adapter/custom_openapi.py +81 -2
- mcp_proxy_adapter/examples/README.md +124 -0
- mcp_proxy_adapter/examples/__init__.py +7 -0
- mcp_proxy_adapter/examples/basic_server/README.md +60 -0
- mcp_proxy_adapter/examples/basic_server/__init__.py +7 -0
- mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +39 -0
- mcp_proxy_adapter/examples/basic_server/config.json +35 -0
- mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +238 -0
- mcp_proxy_adapter/examples/basic_server/server.py +98 -0
- mcp_proxy_adapter/examples/custom_commands/README.md +127 -0
- mcp_proxy_adapter/examples/custom_commands/__init__.py +27 -0
- mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +250 -0
- mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +6 -0
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +103 -0
- mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +111 -0
- mcp_proxy_adapter/examples/custom_commands/config.json +62 -0
- mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +169 -0
- mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +215 -0
- mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +76 -0
- mcp_proxy_adapter/examples/custom_commands/custom_settings.json +96 -0
- mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +241 -0
- mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +135 -0
- mcp_proxy_adapter/examples/custom_commands/echo_command.py +122 -0
- mcp_proxy_adapter/examples/custom_commands/hooks.py +230 -0
- mcp_proxy_adapter/examples/custom_commands/intercept_command.py +123 -0
- mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +103 -0
- mcp_proxy_adapter/examples/custom_commands/server.py +223 -0
- mcp_proxy_adapter/examples/custom_commands/test_hooks.py +176 -0
- mcp_proxy_adapter/examples/deployment/README.md +49 -0
- mcp_proxy_adapter/examples/deployment/__init__.py +7 -0
- mcp_proxy_adapter/examples/deployment/config.development.json +8 -0
- {examples/basic_example → mcp_proxy_adapter/examples/deployment}/config.json +11 -7
- mcp_proxy_adapter/examples/deployment/config.production.json +12 -0
- mcp_proxy_adapter/examples/deployment/config.staging.json +11 -0
- mcp_proxy_adapter/examples/deployment/docker-compose.yml +31 -0
- mcp_proxy_adapter/examples/deployment/run.sh +43 -0
- mcp_proxy_adapter/examples/deployment/run_docker.sh +84 -0
- mcp_proxy_adapter/openapi.py +3 -2
- mcp_proxy_adapter/tests/api/test_custom_openapi.py +617 -0
- mcp_proxy_adapter/tests/api/test_handlers.py +522 -0
- mcp_proxy_adapter/tests/api/test_schemas.py +546 -0
- mcp_proxy_adapter/tests/api/test_tool_integration.py +531 -0
- mcp_proxy_adapter/tests/unit/test_base_command.py +391 -85
- mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-3.1.6.dist-info → mcp_proxy_adapter-4.0.0.dist-info}/METADATA +1 -1
- mcp_proxy_adapter-4.0.0.dist-info/RECORD +110 -0
- {mcp_proxy_adapter-3.1.6.dist-info → mcp_proxy_adapter-4.0.0.dist-info}/WHEEL +1 -1
- {mcp_proxy_adapter-3.1.6.dist-info → mcp_proxy_adapter-4.0.0.dist-info}/top_level.txt +0 -1
- examples/__init__.py +0 -19
- examples/anti_patterns/README.md +0 -51
- examples/anti_patterns/__init__.py +0 -9
- examples/anti_patterns/bad_design/README.md +0 -72
- examples/anti_patterns/bad_design/global_state.py +0 -170
- examples/anti_patterns/bad_design/monolithic_command.py +0 -272
- examples/basic_example/README.md +0 -245
- examples/basic_example/__init__.py +0 -8
- examples/basic_example/commands/__init__.py +0 -5
- examples/basic_example/commands/echo_command.py +0 -95
- examples/basic_example/commands/math_command.py +0 -151
- examples/basic_example/commands/time_command.py +0 -152
- examples/basic_example/docs/EN/README.md +0 -177
- examples/basic_example/docs/RU/README.md +0 -177
- examples/basic_example/server.py +0 -151
- examples/basic_example/tests/conftest.py +0 -243
- examples/check_vstl_schema.py +0 -106
- examples/commands/echo_command.py +0 -52
- examples/commands/echo_command_di.py +0 -152
- examples/commands/echo_result.py +0 -65
- examples/commands/get_date_command.py +0 -98
- examples/commands/new_uuid4_command.py +0 -91
- examples/complete_example/Dockerfile +0 -24
- examples/complete_example/README.md +0 -92
- examples/complete_example/__init__.py +0 -8
- examples/complete_example/commands/__init__.py +0 -5
- examples/complete_example/commands/system_command.py +0 -328
- examples/complete_example/config.json +0 -41
- examples/complete_example/configs/config.dev.yaml +0 -40
- examples/complete_example/configs/config.docker.yaml +0 -40
- examples/complete_example/docker-compose.yml +0 -35
- examples/complete_example/requirements.txt +0 -20
- examples/complete_example/server.py +0 -113
- examples/di_example/.pytest_cache/README.md +0 -8
- examples/di_example/server.py +0 -249
- examples/fix_vstl_help.py +0 -123
- examples/minimal_example/README.md +0 -65
- examples/minimal_example/__init__.py +0 -8
- examples/minimal_example/config.json +0 -14
- examples/minimal_example/main.py +0 -136
- examples/minimal_example/simple_server.py +0 -163
- examples/minimal_example/tests/conftest.py +0 -171
- examples/minimal_example/tests/test_hello_command.py +0 -111
- examples/minimal_example/tests/test_integration.py +0 -181
- examples/patch_vstl_service.py +0 -105
- examples/patch_vstl_service_mcp.py +0 -108
- examples/server.py +0 -69
- examples/simple_server.py +0 -128
- examples/test_package_3.1.4.py +0 -177
- examples/test_server.py +0 -134
- examples/tool_description_example.py +0 -82
- mcp_proxy_adapter/py.typed +0 -0
- mcp_proxy_adapter-3.1.6.dist-info/RECORD +0 -118
- {mcp_proxy_adapter-3.1.6.dist-info → mcp_proxy_adapter-4.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,250 @@
|
|
1
|
+
"""
|
2
|
+
Advanced Hooks Example
|
3
|
+
|
4
|
+
This module demonstrates advanced hook capabilities:
|
5
|
+
1. Data transformation hooks - modify input data before command execution and format output after
|
6
|
+
2. Interception hooks - completely bypass command execution based on conditions
|
7
|
+
"""
|
8
|
+
|
9
|
+
import time
|
10
|
+
import logging
|
11
|
+
from typing import Dict, Any
|
12
|
+
from datetime import datetime
|
13
|
+
|
14
|
+
from mcp_proxy_adapter.commands.hooks import HookContext, HookType
|
15
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
16
|
+
|
17
|
+
|
18
|
+
# Setup logging for advanced hooks
|
19
|
+
logger = logging.getLogger("mcp_proxy_adapter.examples.advanced_hooks")
|
20
|
+
|
21
|
+
|
22
|
+
def data_transform_before_hook(context: HookContext) -> None:
|
23
|
+
"""
|
24
|
+
Before hook for data_transform command - modifies input data.
|
25
|
+
|
26
|
+
Args:
|
27
|
+
context: Hook context with command information
|
28
|
+
"""
|
29
|
+
logger.info(f"🔄 Data transform before hook: {context.params}")
|
30
|
+
|
31
|
+
# Get original data
|
32
|
+
original_data = context.params.get("data", {})
|
33
|
+
|
34
|
+
# Transform data before command execution
|
35
|
+
transformed_data = {}
|
36
|
+
for key, value in original_data.items():
|
37
|
+
if isinstance(value, str):
|
38
|
+
# Add prefix and suffix to string values
|
39
|
+
transformed_data[f"pre_{key}_post"] = f"ENHANCED_{value}_PROCESSED"
|
40
|
+
elif isinstance(value, (int, float)):
|
41
|
+
# Multiply numeric values by 2
|
42
|
+
transformed_data[f"doubled_{key}"] = value * 2
|
43
|
+
else:
|
44
|
+
# Keep other types as is
|
45
|
+
transformed_data[key] = value
|
46
|
+
|
47
|
+
# Add metadata
|
48
|
+
transformed_data["_hook_modified"] = True
|
49
|
+
transformed_data["_modification_time"] = datetime.now().isoformat()
|
50
|
+
|
51
|
+
# Replace original data with transformed data
|
52
|
+
context.params["data"] = transformed_data
|
53
|
+
context.params["data_modified"] = True
|
54
|
+
|
55
|
+
logger.info(f"📊 Original data: {original_data}")
|
56
|
+
logger.info(f"🔄 Transformed data: {transformed_data}")
|
57
|
+
|
58
|
+
|
59
|
+
def data_transform_after_hook(context: HookContext) -> None:
|
60
|
+
"""
|
61
|
+
After hook for data_transform command - formats output data.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
context: Hook context with command information
|
65
|
+
"""
|
66
|
+
logger.info(f"🔄 Data transform after hook: {context.result}")
|
67
|
+
|
68
|
+
if context.result and hasattr(context.result, 'transformed_data'):
|
69
|
+
# Get the transformed data from command result
|
70
|
+
transformed_data = context.result.transformed_data
|
71
|
+
|
72
|
+
# Apply additional formatting
|
73
|
+
formatted_data = {}
|
74
|
+
for key, value in transformed_data.items():
|
75
|
+
if isinstance(value, str):
|
76
|
+
# Add formatting to string values
|
77
|
+
formatted_data[f"formatted_{key}"] = f"✨ {value} ✨"
|
78
|
+
else:
|
79
|
+
formatted_data[key] = value
|
80
|
+
|
81
|
+
# Add formatting metadata
|
82
|
+
formatted_data["_formatted_by_hook"] = True
|
83
|
+
formatted_data["_formatting_time"] = datetime.now().isoformat()
|
84
|
+
|
85
|
+
# Update the result with formatted data
|
86
|
+
context.result.transformed_data = formatted_data
|
87
|
+
|
88
|
+
logger.info(f"✨ Formatted data: {formatted_data}")
|
89
|
+
|
90
|
+
|
91
|
+
def intercept_before_hook(context: HookContext) -> None:
|
92
|
+
"""
|
93
|
+
Before hook for intercept command - can completely bypass execution.
|
94
|
+
|
95
|
+
Args:
|
96
|
+
context: Hook context with command information
|
97
|
+
"""
|
98
|
+
logger.info(f"🚫 Intercept before hook: {context.params}")
|
99
|
+
|
100
|
+
# Check bypass flag
|
101
|
+
bypass_flag = context.params.get("bypass_flag", 1)
|
102
|
+
|
103
|
+
if bypass_flag == 0:
|
104
|
+
# Completely bypass command execution
|
105
|
+
logger.info(f"🚫 Intercepting command execution - bypass_flag = 0")
|
106
|
+
|
107
|
+
# Create a mock result without calling the actual command
|
108
|
+
from .intercept_command import InterceptResult
|
109
|
+
|
110
|
+
mock_result = InterceptResult(
|
111
|
+
message="Command intercepted by hook - not executed",
|
112
|
+
executed=False,
|
113
|
+
intercept_reason="bypass_flag = 0",
|
114
|
+
hook_data={
|
115
|
+
"intercepted_by": "intercept_before_hook",
|
116
|
+
"interception_time": datetime.now().isoformat(),
|
117
|
+
"original_params": context.params.copy()
|
118
|
+
}
|
119
|
+
)
|
120
|
+
|
121
|
+
# Set the result and stop standard processing
|
122
|
+
context.result = mock_result
|
123
|
+
context.standard_processing = False
|
124
|
+
|
125
|
+
logger.info(f"✅ Command intercepted successfully")
|
126
|
+
else:
|
127
|
+
# Allow normal execution
|
128
|
+
logger.info(f"✅ Allowing normal execution - bypass_flag = {bypass_flag}")
|
129
|
+
context.params["hook_processed"] = True
|
130
|
+
|
131
|
+
|
132
|
+
def intercept_after_hook(context: HookContext) -> None:
|
133
|
+
"""
|
134
|
+
After hook for intercept command.
|
135
|
+
|
136
|
+
Args:
|
137
|
+
context: Hook context with command information
|
138
|
+
"""
|
139
|
+
if context.standard_processing:
|
140
|
+
logger.info(f"✅ Intercept command executed normally")
|
141
|
+
else:
|
142
|
+
logger.info(f"🚫 Intercept command was intercepted by hook")
|
143
|
+
|
144
|
+
# Add execution metadata
|
145
|
+
if context.result and hasattr(context.result, 'hook_data'):
|
146
|
+
context.result.hook_data["after_hook_processed"] = True
|
147
|
+
context.result.hook_data["after_hook_time"] = datetime.now().isoformat()
|
148
|
+
|
149
|
+
|
150
|
+
def conditional_transform_hook(context: HookContext) -> None:
|
151
|
+
"""
|
152
|
+
Conditional transformation hook - applies different transformations based on data.
|
153
|
+
|
154
|
+
Args:
|
155
|
+
context: Hook context with command information
|
156
|
+
"""
|
157
|
+
if context.hook_type == HookType.BEFORE_EXECUTION:
|
158
|
+
logger.info(f"🎯 Conditional transform before hook: {context.command_name}")
|
159
|
+
|
160
|
+
# Check if this is a data_transform command
|
161
|
+
if context.command_name == "data_transform":
|
162
|
+
data = context.params.get("data", {})
|
163
|
+
transform_type = context.params.get("transform_type", "default")
|
164
|
+
|
165
|
+
# Apply conditional transformation based on data content
|
166
|
+
if "special" in str(data).lower():
|
167
|
+
logger.info(f"🎯 Special data detected - applying enhanced transformation")
|
168
|
+
context.params["transform_type"] = "uppercase"
|
169
|
+
context.params["_special_enhancement"] = True
|
170
|
+
elif "test" in str(data).lower():
|
171
|
+
logger.info(f"🎯 Test data detected - applying test transformation")
|
172
|
+
context.params["transform_type"] = "reverse"
|
173
|
+
context.params["_test_mode"] = True
|
174
|
+
|
175
|
+
elif context.hook_type == HookType.AFTER_EXECUTION:
|
176
|
+
logger.info(f"🎯 Conditional transform after hook: {context.command_name}")
|
177
|
+
|
178
|
+
# Add conditional metadata to result
|
179
|
+
if context.result and hasattr(context.result, 'processing_info'):
|
180
|
+
context.result.processing_info["conditional_processed"] = True
|
181
|
+
context.result.processing_info["conditional_time"] = datetime.now().isoformat()
|
182
|
+
|
183
|
+
|
184
|
+
def smart_intercept_hook(context: HookContext) -> None:
|
185
|
+
"""
|
186
|
+
Smart interception hook - intercepts based on multiple conditions.
|
187
|
+
|
188
|
+
Args:
|
189
|
+
context: Hook context with command information
|
190
|
+
"""
|
191
|
+
if context.hook_type == HookType.BEFORE_EXECUTION:
|
192
|
+
logger.info(f"🧠 Smart intercept before hook: {context.command_name}")
|
193
|
+
|
194
|
+
# Check multiple conditions for interception
|
195
|
+
action = context.params.get("action", "")
|
196
|
+
bypass_flag = context.params.get("bypass_flag", 1)
|
197
|
+
|
198
|
+
# Intercept if action is "blocked" or bypass_flag is 0
|
199
|
+
if action == "blocked" or bypass_flag == 0:
|
200
|
+
logger.info(f"🧠 Smart intercept: action='{action}', bypass_flag={bypass_flag}")
|
201
|
+
|
202
|
+
# Create intercepted result
|
203
|
+
from .intercept_command import InterceptResult
|
204
|
+
|
205
|
+
intercept_reason = "blocked_action" if action == "blocked" else "bypass_flag_zero"
|
206
|
+
|
207
|
+
mock_result = InterceptResult(
|
208
|
+
message=f"Command intercepted by smart hook - reason: {intercept_reason}",
|
209
|
+
executed=False,
|
210
|
+
intercept_reason=intercept_reason,
|
211
|
+
hook_data={
|
212
|
+
"intercepted_by": "smart_intercept_hook",
|
213
|
+
"interception_time": datetime.now().isoformat(),
|
214
|
+
"original_params": context.params.copy(),
|
215
|
+
"smart_analysis": True
|
216
|
+
}
|
217
|
+
)
|
218
|
+
|
219
|
+
# Set the result and stop standard processing
|
220
|
+
context.result = mock_result
|
221
|
+
context.standard_processing = False
|
222
|
+
|
223
|
+
logger.info(f"✅ Smart interception completed")
|
224
|
+
|
225
|
+
|
226
|
+
def register_advanced_hooks(hooks_manager) -> None:
|
227
|
+
"""
|
228
|
+
Register advanced hooks with the hooks manager.
|
229
|
+
|
230
|
+
Args:
|
231
|
+
hooks_manager: The hooks manager instance
|
232
|
+
"""
|
233
|
+
logger.info("🔧 Registering advanced hooks...")
|
234
|
+
|
235
|
+
# Register data transformation hooks
|
236
|
+
hooks_manager.register_before_hook("data_transform", data_transform_before_hook)
|
237
|
+
hooks_manager.register_after_hook("data_transform", data_transform_after_hook)
|
238
|
+
|
239
|
+
# Register interception hooks
|
240
|
+
hooks_manager.register_before_hook("intercept", intercept_before_hook)
|
241
|
+
hooks_manager.register_after_hook("intercept", intercept_after_hook)
|
242
|
+
|
243
|
+
# Register conditional hooks
|
244
|
+
hooks_manager.register_global_before_hook(conditional_transform_hook)
|
245
|
+
hooks_manager.register_global_after_hook(conditional_transform_hook)
|
246
|
+
|
247
|
+
# Register smart interception hooks
|
248
|
+
hooks_manager.register_global_before_hook(smart_intercept_hook)
|
249
|
+
|
250
|
+
logger.info("✅ Advanced hooks registered successfully")
|
@@ -0,0 +1,103 @@
|
|
1
|
+
"""
|
2
|
+
Auto-registered Echo Command
|
3
|
+
|
4
|
+
This command will be automatically discovered and registered by the framework.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Dict, Any, Optional
|
8
|
+
from mcp_proxy_adapter.commands.base import Command
|
9
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
10
|
+
|
11
|
+
|
12
|
+
class AutoEchoResult(CommandResult):
|
13
|
+
"""
|
14
|
+
Result of the auto-registered echo command execution.
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __init__(self, message: str, auto_registered: bool = True):
|
18
|
+
"""
|
19
|
+
Initialize auto echo command result.
|
20
|
+
|
21
|
+
Args:
|
22
|
+
message: Echoed message
|
23
|
+
auto_registered: Flag indicating this was auto-registered
|
24
|
+
"""
|
25
|
+
self.message = message
|
26
|
+
self.auto_registered = auto_registered
|
27
|
+
|
28
|
+
def to_dict(self) -> Dict[str, Any]:
|
29
|
+
"""
|
30
|
+
Convert result to dictionary.
|
31
|
+
|
32
|
+
Returns:
|
33
|
+
Dict[str, Any]: Result as dictionary
|
34
|
+
"""
|
35
|
+
return {
|
36
|
+
"message": self.message,
|
37
|
+
"auto_registered": self.auto_registered,
|
38
|
+
"command_type": "auto_echo"
|
39
|
+
}
|
40
|
+
|
41
|
+
@classmethod
|
42
|
+
def get_schema(cls) -> Dict[str, Any]:
|
43
|
+
"""
|
44
|
+
Get JSON schema for the result.
|
45
|
+
|
46
|
+
Returns:
|
47
|
+
Dict[str, Any]: JSON schema
|
48
|
+
"""
|
49
|
+
return {
|
50
|
+
"type": "object",
|
51
|
+
"properties": {
|
52
|
+
"message": {"type": "string"},
|
53
|
+
"auto_registered": {"type": "boolean"},
|
54
|
+
"command_type": {"type": "string"}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
class AutoEchoCommand(Command):
|
60
|
+
"""
|
61
|
+
Auto-registered echo command.
|
62
|
+
"""
|
63
|
+
|
64
|
+
name = "auto_echo"
|
65
|
+
result_class = AutoEchoResult
|
66
|
+
|
67
|
+
async def execute(self, message: Optional[str] = None, **kwargs) -> AutoEchoResult:
|
68
|
+
"""
|
69
|
+
Execute auto-registered echo command.
|
70
|
+
|
71
|
+
Args:
|
72
|
+
message: Message to echo
|
73
|
+
**kwargs: Additional parameters
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
AutoEchoResult: Auto echo command result
|
77
|
+
"""
|
78
|
+
if message is None:
|
79
|
+
message = "Hello from auto-registered command!"
|
80
|
+
|
81
|
+
return AutoEchoResult(
|
82
|
+
message=message,
|
83
|
+
auto_registered=True
|
84
|
+
)
|
85
|
+
|
86
|
+
@classmethod
|
87
|
+
def get_schema(cls) -> Dict[str, Any]:
|
88
|
+
"""
|
89
|
+
Get JSON schema for command parameters.
|
90
|
+
|
91
|
+
Returns:
|
92
|
+
Dict[str, Any]: JSON schema
|
93
|
+
"""
|
94
|
+
return {
|
95
|
+
"type": "object",
|
96
|
+
"properties": {
|
97
|
+
"message": {
|
98
|
+
"type": "string",
|
99
|
+
"description": "Message to echo",
|
100
|
+
"default": "Hello from auto-registered command!"
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
@@ -0,0 +1,111 @@
|
|
1
|
+
"""
|
2
|
+
Auto-registered Info Command
|
3
|
+
|
4
|
+
This command will be automatically discovered and registered by the framework.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Dict, Any, Optional
|
8
|
+
from mcp_proxy_adapter.commands.base import Command
|
9
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
10
|
+
|
11
|
+
|
12
|
+
class AutoInfoResult(CommandResult):
|
13
|
+
"""
|
14
|
+
Result of the auto-registered info command execution.
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __init__(self, info: Dict[str, Any], auto_registered: bool = True):
|
18
|
+
"""
|
19
|
+
Initialize auto info command result.
|
20
|
+
|
21
|
+
Args:
|
22
|
+
info: Information data
|
23
|
+
auto_registered: Flag indicating this was auto-registered
|
24
|
+
"""
|
25
|
+
self.info = info
|
26
|
+
self.auto_registered = auto_registered
|
27
|
+
|
28
|
+
def to_dict(self) -> Dict[str, Any]:
|
29
|
+
"""
|
30
|
+
Convert result to dictionary.
|
31
|
+
|
32
|
+
Returns:
|
33
|
+
Dict[str, Any]: Result as dictionary
|
34
|
+
"""
|
35
|
+
return {
|
36
|
+
"info": self.info,
|
37
|
+
"auto_registered": self.auto_registered,
|
38
|
+
"command_type": "auto_info"
|
39
|
+
}
|
40
|
+
|
41
|
+
@classmethod
|
42
|
+
def get_schema(cls) -> Dict[str, Any]:
|
43
|
+
"""
|
44
|
+
Get JSON schema for the result.
|
45
|
+
|
46
|
+
Returns:
|
47
|
+
Dict[str, Any]: JSON schema
|
48
|
+
"""
|
49
|
+
return {
|
50
|
+
"type": "object",
|
51
|
+
"properties": {
|
52
|
+
"info": {"type": "object"},
|
53
|
+
"auto_registered": {"type": "boolean"},
|
54
|
+
"command_type": {"type": "string"}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
class AutoInfoCommand(Command):
|
60
|
+
"""
|
61
|
+
Auto-registered info command.
|
62
|
+
"""
|
63
|
+
|
64
|
+
name = "auto_info"
|
65
|
+
result_class = AutoInfoResult
|
66
|
+
|
67
|
+
async def execute(self, topic: Optional[str] = None, **kwargs) -> AutoInfoResult:
|
68
|
+
"""
|
69
|
+
Execute auto-registered info command.
|
70
|
+
|
71
|
+
Args:
|
72
|
+
topic: Information topic
|
73
|
+
**kwargs: Additional parameters
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
AutoInfoResult: Auto info command result
|
77
|
+
"""
|
78
|
+
if topic is None:
|
79
|
+
topic = "general"
|
80
|
+
|
81
|
+
info_data = {
|
82
|
+
"topic": topic,
|
83
|
+
"auto_registered": True,
|
84
|
+
"discovery_method": "automatic",
|
85
|
+
"registration_time": "startup",
|
86
|
+
"command_type": "auto_info"
|
87
|
+
}
|
88
|
+
|
89
|
+
return AutoInfoResult(
|
90
|
+
info=info_data,
|
91
|
+
auto_registered=True
|
92
|
+
)
|
93
|
+
|
94
|
+
@classmethod
|
95
|
+
def get_schema(cls) -> Dict[str, Any]:
|
96
|
+
"""
|
97
|
+
Get JSON schema for command parameters.
|
98
|
+
|
99
|
+
Returns:
|
100
|
+
Dict[str, Any]: JSON schema
|
101
|
+
"""
|
102
|
+
return {
|
103
|
+
"type": "object",
|
104
|
+
"properties": {
|
105
|
+
"topic": {
|
106
|
+
"type": "string",
|
107
|
+
"description": "Information topic",
|
108
|
+
"default": "general"
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
{
|
2
|
+
"server": {
|
3
|
+
"host": "0.0.0.0",
|
4
|
+
"port": 8000,
|
5
|
+
"debug": true,
|
6
|
+
"log_level": "DEBUG"
|
7
|
+
},
|
8
|
+
"logging": {
|
9
|
+
"level": "DEBUG",
|
10
|
+
"log_dir": "./logs/custom_commands",
|
11
|
+
"log_file": "custom_commands.log",
|
12
|
+
"error_log_file": "custom_commands_error.log",
|
13
|
+
"access_log_file": "custom_commands_access.log",
|
14
|
+
"max_file_size": "10MB",
|
15
|
+
"backup_count": 5,
|
16
|
+
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
17
|
+
"date_format": "%Y-%m-%d %H:%M:%S",
|
18
|
+
"console_output": true,
|
19
|
+
"file_output": true
|
20
|
+
},
|
21
|
+
"commands": {
|
22
|
+
"auto_discovery": true,
|
23
|
+
"discovery_path": "mcp_proxy_adapter.commands",
|
24
|
+
"custom_commands_path": "./custom_commands",
|
25
|
+
"auto_commands_path": "mcp_proxy_adapter.examples.custom_commands.auto_commands"
|
26
|
+
},
|
27
|
+
"custom": {
|
28
|
+
"server_name": "Advanced MCP Proxy Server with Hooks",
|
29
|
+
"description": "Extended example server with custom commands and hooks",
|
30
|
+
"features": {
|
31
|
+
"hooks_enabled": true,
|
32
|
+
"custom_commands_enabled": true,
|
33
|
+
"advanced_logging": true,
|
34
|
+
"data_transformation": true,
|
35
|
+
"command_interception": true
|
36
|
+
},
|
37
|
+
"hooks": {
|
38
|
+
"data_transform": {
|
39
|
+
"enabled": true,
|
40
|
+
"transform_types": ["uppercase", "lowercase", "reverse"]
|
41
|
+
},
|
42
|
+
"intercept": {
|
43
|
+
"enabled": true,
|
44
|
+
"bypass_conditions": ["input_value == 0"]
|
45
|
+
}
|
46
|
+
},
|
47
|
+
"custom_commands": {
|
48
|
+
"manual_echo": {
|
49
|
+
"enabled": true,
|
50
|
+
"description": "Manually registered echo command"
|
51
|
+
},
|
52
|
+
"data_transform": {
|
53
|
+
"enabled": true,
|
54
|
+
"description": "Data transformation command"
|
55
|
+
},
|
56
|
+
"intercept": {
|
57
|
+
"enabled": true,
|
58
|
+
"description": "Command interception example"
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|