mcp-proxy-adapter 4.1.0__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 +705 -345
- 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 +17 -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 +97 -41
- 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 -63
- 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.0.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.0.dist-info/RECORD +0 -110
- {mcp_proxy_adapter-4.1.0.dist-info → mcp_proxy_adapter-6.0.0.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-4.1.0.dist-info → mcp_proxy_adapter-6.0.0.dist-info}/licenses/LICENSE +0 -0
- {mcp_proxy_adapter-4.1.0.dist-info → mcp_proxy_adapter-6.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,278 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Server startup script with proper registration sequence.
|
4
|
+
First starts the server, then registers with proxy after server is ready.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import asyncio
|
8
|
+
import time
|
9
|
+
import sys
|
10
|
+
import os
|
11
|
+
import uvicorn
|
12
|
+
import threading
|
13
|
+
from pathlib import Path
|
14
|
+
|
15
|
+
# Add parent directories to path
|
16
|
+
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
17
|
+
|
18
|
+
from mcp_proxy_adapter import create_app
|
19
|
+
from mcp_proxy_adapter.core.logging import get_logger, setup_logging
|
20
|
+
from mcp_proxy_adapter.core.settings import (
|
21
|
+
Settings,
|
22
|
+
get_server_host,
|
23
|
+
get_server_port,
|
24
|
+
get_server_debug,
|
25
|
+
get_setting,
|
26
|
+
get_custom_setting_value
|
27
|
+
)
|
28
|
+
from mcp_proxy_adapter.core.ssl_utils import SSLUtils
|
29
|
+
from mcp_proxy_adapter.core.transport_manager import transport_manager
|
30
|
+
from mcp_proxy_adapter.core.proxy_registration import register_with_proxy
|
31
|
+
from custom_settings_manager import CustomSettingsManager, get_app_name, is_feature_enabled
|
32
|
+
|
33
|
+
# Import custom commands and hooks
|
34
|
+
from custom_help_command import CustomHelpCommand
|
35
|
+
from custom_health_command import CustomHealthCommand
|
36
|
+
from data_transform_command import DataTransformCommand
|
37
|
+
from intercept_command import InterceptCommand
|
38
|
+
from advanced_hooks import register_advanced_hooks
|
39
|
+
|
40
|
+
# Import auto-registered commands
|
41
|
+
from auto_commands.auto_echo_command import AutoEchoCommand
|
42
|
+
from auto_commands.auto_info_command import AutoInfoCommand
|
43
|
+
|
44
|
+
# Import manual registration example
|
45
|
+
from manual_echo_command import ManualEchoCommand
|
46
|
+
|
47
|
+
# Import echo command
|
48
|
+
from echo_command import EchoCommand
|
49
|
+
|
50
|
+
# Import custom OpenAPI generator
|
51
|
+
from custom_openapi_generator import custom_openapi_generator
|
52
|
+
|
53
|
+
# Import command registry for manual registration
|
54
|
+
from mcp_proxy_adapter.commands.command_registry import registry
|
55
|
+
from mcp_proxy_adapter.config import config
|
56
|
+
from mcp_proxy_adapter.commands.hooks import register_custom_commands_hook
|
57
|
+
|
58
|
+
|
59
|
+
def custom_commands_hook(registry):
|
60
|
+
"""Hook function for registering custom commands."""
|
61
|
+
logger = get_logger("custom_commands")
|
62
|
+
logger.info("Registering custom commands via hook...")
|
63
|
+
|
64
|
+
# Get custom commands configuration from custom settings
|
65
|
+
custom_commands_config = get_custom_setting_value("custom_commands", {})
|
66
|
+
|
67
|
+
# Register echo command (only if not already registered)
|
68
|
+
if not registry.command_exists("echo"):
|
69
|
+
registry.register_custom(EchoCommand)
|
70
|
+
logger.info("Registered: echo command")
|
71
|
+
else:
|
72
|
+
logger.debug("Command 'echo' is already registered, skipping")
|
73
|
+
|
74
|
+
# Register custom help command (will override built-in)
|
75
|
+
if custom_commands_config.get("help", {}).get("enabled", True):
|
76
|
+
registry.register_custom(CustomHelpCommand)
|
77
|
+
logger.info("Registered: custom help command")
|
78
|
+
|
79
|
+
# Register custom health command (will override built-in)
|
80
|
+
if custom_commands_config.get("health", {}).get("enabled", True):
|
81
|
+
registry.register_custom(CustomHealthCommand)
|
82
|
+
logger.info("Registered: custom health command")
|
83
|
+
|
84
|
+
# Register advanced demonstration commands
|
85
|
+
if custom_commands_config.get("data_transform", {}).get("enabled", True):
|
86
|
+
registry.register_custom(DataTransformCommand)
|
87
|
+
logger.info("Registered: data_transform command")
|
88
|
+
|
89
|
+
if custom_commands_config.get("intercept", {}).get("enabled", True):
|
90
|
+
registry.register_custom(InterceptCommand)
|
91
|
+
logger.info("Registered: intercept command")
|
92
|
+
|
93
|
+
|
94
|
+
def setup_hooks():
|
95
|
+
"""Setup hooks for command processing."""
|
96
|
+
logger = get_logger("custom_commands")
|
97
|
+
logger.info("Setting up hooks...")
|
98
|
+
|
99
|
+
# Register custom commands hook
|
100
|
+
register_custom_commands_hook(custom_commands_hook)
|
101
|
+
|
102
|
+
# Note: Advanced hooks are not compatible with current API
|
103
|
+
# They will be registered automatically by the command registry
|
104
|
+
logger.info("Basic hooks setup completed")
|
105
|
+
|
106
|
+
|
107
|
+
async def initialize_commands():
|
108
|
+
"""
|
109
|
+
Initialize commands using the unified system initialization logic.
|
110
|
+
This function is used both at startup and during reload.
|
111
|
+
|
112
|
+
Returns:
|
113
|
+
Number of commands discovered.
|
114
|
+
"""
|
115
|
+
# Use the unified reload method from registry
|
116
|
+
result = await registry.reload_system()
|
117
|
+
return result["total_commands"]
|
118
|
+
|
119
|
+
|
120
|
+
async def register_with_proxy_after_startup():
|
121
|
+
"""
|
122
|
+
Register with proxy after server is fully started and listening.
|
123
|
+
"""
|
124
|
+
logger = get_logger("proxy_registration")
|
125
|
+
|
126
|
+
# Wait a bit for server to fully start
|
127
|
+
await asyncio.sleep(3)
|
128
|
+
|
129
|
+
# Get server configuration
|
130
|
+
server_config = config.get("server", {})
|
131
|
+
server_host = server_config.get("host", "0.0.0.0")
|
132
|
+
server_port = server_config.get("port", 8000)
|
133
|
+
|
134
|
+
# Use localhost for external access if host is 0.0.0.0
|
135
|
+
if server_host == "0.0.0.0":
|
136
|
+
server_host = "localhost"
|
137
|
+
|
138
|
+
server_url = f"http://{server_host}:{server_port}"
|
139
|
+
|
140
|
+
logger.info(f"Attempting to register server with proxy at {server_url}")
|
141
|
+
|
142
|
+
# Attempt registration
|
143
|
+
registration_success = await register_with_proxy(server_url)
|
144
|
+
if registration_success:
|
145
|
+
logger.info("✅ Successfully registered with proxy after server startup")
|
146
|
+
else:
|
147
|
+
logger.warning("⚠️ Failed to register with proxy after server startup")
|
148
|
+
|
149
|
+
|
150
|
+
def start_server():
|
151
|
+
"""Start the server in a separate thread."""
|
152
|
+
# Initialize settings
|
153
|
+
settings = Settings()
|
154
|
+
server_settings = settings.get_server_settings()
|
155
|
+
logging_settings = settings.get_logging_settings()
|
156
|
+
commands_settings = settings.get_commands_settings()
|
157
|
+
|
158
|
+
# Setup logging - pass only the level, not the entire dict
|
159
|
+
setup_logging(logging_settings.get('level', 'INFO'))
|
160
|
+
logger = get_logger("server_startup")
|
161
|
+
|
162
|
+
# Load transport configuration
|
163
|
+
if not transport_manager.load_config(config.config_data):
|
164
|
+
logger.error("Failed to load transport configuration")
|
165
|
+
return
|
166
|
+
|
167
|
+
# Validate transport configuration
|
168
|
+
if not transport_manager.validate_config():
|
169
|
+
logger.error("Transport configuration validation failed")
|
170
|
+
return
|
171
|
+
|
172
|
+
# Print server header and description
|
173
|
+
print("=" * 80)
|
174
|
+
print("🔧 ADVANCED MCP PROXY ADAPTER SERVER WITH HOOKS")
|
175
|
+
print("=" * 80)
|
176
|
+
print("📋 Description:")
|
177
|
+
print(f" {get_app_name()} - Advanced server with custom settings management")
|
178
|
+
print()
|
179
|
+
|
180
|
+
# Get transport info
|
181
|
+
transport_info = transport_manager.get_transport_info()
|
182
|
+
|
183
|
+
print("⚙️ Configuration:")
|
184
|
+
print(f" • Server: {server_settings['host']}:{transport_manager.get_port()}")
|
185
|
+
print(f" • Transport: {transport_info['type']}")
|
186
|
+
print(f" • Debug: {server_settings['debug']}")
|
187
|
+
print(f" • Log Level: {logging_settings.get('level', 'INFO')}")
|
188
|
+
print(f" • Log Directory: {logging_settings.get('log_dir', './logs')}")
|
189
|
+
print(f" • Auto Discovery: {commands_settings['auto_discovery']}")
|
190
|
+
print(f" • SSL Enabled: {transport_info['ssl_enabled']}")
|
191
|
+
if transport_info['ssl_enabled']:
|
192
|
+
ssl_config = transport_info['ssl_config']
|
193
|
+
print(f" • SSL Cert: {ssl_config.get('cert_file', 'Not specified')}")
|
194
|
+
print(f" • Client Verification: {ssl_config.get('verify_client', False)}")
|
195
|
+
print()
|
196
|
+
print("🔧 Available Commands:")
|
197
|
+
print(" • help - Custom help command (overrides built-in)")
|
198
|
+
print(" • health - Custom health command (overrides built-in)")
|
199
|
+
print(" • config - Built-in config command")
|
200
|
+
print(" • reload - Built-in reload command")
|
201
|
+
print(" • settings - Built-in settings command")
|
202
|
+
print(" • load - Built-in load command")
|
203
|
+
print(" • unload - Built-in unload command")
|
204
|
+
print(" • plugins - Built-in plugins command")
|
205
|
+
print(" • echo - Custom echo command")
|
206
|
+
print(" • data_transform - Data transformation command")
|
207
|
+
print(" • intercept - Command interception example")
|
208
|
+
print(" • manual_echo - Manually registered echo command")
|
209
|
+
print(" • test - Remote command (loaded from plugin server)")
|
210
|
+
print()
|
211
|
+
print("🎯 Features:")
|
212
|
+
print(" • Advanced JSON-RPC API")
|
213
|
+
print(" • Custom commands with hooks")
|
214
|
+
print(" • Data transformation hooks")
|
215
|
+
print(" • Command interception hooks")
|
216
|
+
print(" • Auto-registration and manual registration")
|
217
|
+
print(" • Custom OpenAPI schema generation")
|
218
|
+
print(" • Configuration-driven settings")
|
219
|
+
print(" • Custom settings management")
|
220
|
+
print("=" * 80)
|
221
|
+
print()
|
222
|
+
|
223
|
+
logger.info("Starting Advanced Custom Commands MCP Proxy Adapter Server with Hooks...")
|
224
|
+
logger.info(f"Server configuration: {server_settings}")
|
225
|
+
logger.info(f"Logging configuration: {logging_settings}")
|
226
|
+
logger.info(f"Commands configuration: {commands_settings}")
|
227
|
+
logger.info(f"Transport configuration: {transport_info}")
|
228
|
+
|
229
|
+
# Setup hooks for command processing
|
230
|
+
setup_hooks()
|
231
|
+
|
232
|
+
# Initialize commands
|
233
|
+
asyncio.run(initialize_commands())
|
234
|
+
|
235
|
+
# Create application with settings from configuration
|
236
|
+
app = create_app(
|
237
|
+
title=get_app_name(),
|
238
|
+
description="Advanced MCP Proxy Adapter server with custom settings management, demonstrating hook capabilities including data transformation, command interception, conditional processing, and smart interception hooks. Features custom commands with enhanced functionality and comprehensive settings management.",
|
239
|
+
version="2.1.0"
|
240
|
+
)
|
241
|
+
|
242
|
+
# Get uvicorn configuration from transport manager
|
243
|
+
uvicorn_config = transport_manager.get_uvicorn_config()
|
244
|
+
uvicorn_config["host"] = server_settings['host']
|
245
|
+
uvicorn_config["log_level"] = server_settings['log_level'].lower()
|
246
|
+
|
247
|
+
logger.info(f"Starting server with uvicorn config: {uvicorn_config}")
|
248
|
+
|
249
|
+
# Run the server with configuration settings
|
250
|
+
uvicorn.run(
|
251
|
+
app,
|
252
|
+
**uvicorn_config
|
253
|
+
)
|
254
|
+
|
255
|
+
|
256
|
+
def main():
|
257
|
+
"""Main function to start server and register with proxy."""
|
258
|
+
# Start server in a separate thread
|
259
|
+
server_thread = threading.Thread(target=start_server, daemon=True)
|
260
|
+
server_thread.start()
|
261
|
+
|
262
|
+
# Wait for server to start
|
263
|
+
time.sleep(5)
|
264
|
+
|
265
|
+
# Register with proxy after server is ready
|
266
|
+
asyncio.run(register_with_proxy_after_startup())
|
267
|
+
|
268
|
+
# Keep main thread alive
|
269
|
+
try:
|
270
|
+
while True:
|
271
|
+
time.sleep(1)
|
272
|
+
except KeyboardInterrupt:
|
273
|
+
print("\n🛑 Server shutdown requested")
|
274
|
+
sys.exit(0)
|
275
|
+
|
276
|
+
|
277
|
+
if __name__ == "__main__":
|
278
|
+
main()
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Simple test server to get OpenAPI schema.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import uvicorn
|
7
|
+
from fastapi import FastAPI
|
8
|
+
from mcp_proxy_adapter.custom_openapi import custom_openapi_with_fallback
|
9
|
+
|
10
|
+
# Create FastAPI app
|
11
|
+
app = FastAPI(
|
12
|
+
title="Test MCP Proxy Server",
|
13
|
+
description="Test server for OpenAPI schema",
|
14
|
+
version="1.0.0"
|
15
|
+
)
|
16
|
+
|
17
|
+
# Set custom OpenAPI generator
|
18
|
+
app.openapi = lambda: custom_openapi_with_fallback(app)
|
19
|
+
|
20
|
+
# Add OpenAPI endpoint
|
21
|
+
@app.get("/openapi.json")
|
22
|
+
async def get_openapi_schema():
|
23
|
+
"""Returns OpenAPI schema."""
|
24
|
+
return custom_openapi_with_fallback(app)
|
25
|
+
|
26
|
+
if __name__ == "__main__":
|
27
|
+
uvicorn.run(app, host="0.0.0.0", port=8001)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Test script to understand registry issues.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import sys
|
7
|
+
import os
|
8
|
+
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
9
|
+
|
10
|
+
print("1. Importing registry directly...")
|
11
|
+
from mcp_proxy_adapter.commands.command_registry import registry
|
12
|
+
print(f" Registry type: {type(registry)}")
|
13
|
+
print(f" Registry has reload_system: {hasattr(registry, 'reload_system')}")
|
14
|
+
print(f" Registry methods: {[m for m in dir(registry) if not m.startswith('_')]}")
|
15
|
+
|
16
|
+
print("2. Testing reload_system...")
|
17
|
+
try:
|
18
|
+
result = registry.reload_system()
|
19
|
+
print(f" ✅ reload_system worked: {result}")
|
20
|
+
except Exception as e:
|
21
|
+
print(f" ❌ reload_system failed: {e}")
|
22
|
+
import traceback
|
23
|
+
traceback.print_exc()
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Simple test in custom_commands directory.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import sys
|
7
|
+
import os
|
8
|
+
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
|
9
|
+
|
10
|
+
print("1. Importing registry directly...")
|
11
|
+
from mcp_proxy_adapter.commands.command_registry import registry
|
12
|
+
print(f" Registry has reload_system: {hasattr(registry, 'reload_system')}")
|
13
|
+
|
14
|
+
print("2. Testing reload_system...")
|
15
|
+
try:
|
16
|
+
result = registry.reload_system()
|
17
|
+
print(f" ✅ reload_system worked: {result}")
|
18
|
+
except Exception as e:
|
19
|
+
print(f" ❌ reload_system failed: {e}")
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# Пример пользовательского проекта с командами
|
2
|
+
|
3
|
+
Этот пример показывает, как создать свой проект с командами и настроить `discovery_path` для их автоматического обнаружения.
|
4
|
+
|
5
|
+
## Структура проекта
|
6
|
+
|
7
|
+
```
|
8
|
+
myproject/
|
9
|
+
├── config.json
|
10
|
+
├── main.py
|
11
|
+
├── myproject/
|
12
|
+
│ ├── __init__.py
|
13
|
+
│ └── commands/
|
14
|
+
│ ├── __init__.py
|
15
|
+
│ ├── echo_command.py
|
16
|
+
│ └── info_command.py
|
17
|
+
└── README.md
|
18
|
+
```
|
19
|
+
|
20
|
+
## Конфигурация
|
21
|
+
|
22
|
+
В файле `config.json` указываем путь к нашим командам:
|
23
|
+
|
24
|
+
```json
|
25
|
+
{
|
26
|
+
"server": {
|
27
|
+
"host": "127.0.0.1",
|
28
|
+
"port": 8001,
|
29
|
+
"debug": true,
|
30
|
+
"log_level": "DEBUG"
|
31
|
+
},
|
32
|
+
"logging": {
|
33
|
+
"level": "DEBUG",
|
34
|
+
"log_dir": "./logs",
|
35
|
+
"log_file": "myproject.log"
|
36
|
+
},
|
37
|
+
"commands": {
|
38
|
+
"auto_discovery": true,
|
39
|
+
"discovery_path": "myproject.commands"
|
40
|
+
}
|
41
|
+
}
|
42
|
+
```
|
43
|
+
|
44
|
+
## Команды
|
45
|
+
|
46
|
+
### echo_command.py
|
47
|
+
|
48
|
+
```python
|
49
|
+
from mcp_proxy_adapter.commands.base import Command
|
50
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
51
|
+
|
52
|
+
class EchoCommand(Command):
|
53
|
+
"""Echo command that returns the input text."""
|
54
|
+
|
55
|
+
name = "echo"
|
56
|
+
|
57
|
+
def execute(self, text: str) -> CommandResult:
|
58
|
+
return CommandResult(success=True, data={"echo": text})
|
59
|
+
|
60
|
+
@classmethod
|
61
|
+
def get_param_info(cls) -> dict:
|
62
|
+
return {
|
63
|
+
"text": {
|
64
|
+
"type": "string",
|
65
|
+
"description": "Text to echo",
|
66
|
+
"required": True
|
67
|
+
}
|
68
|
+
}
|
69
|
+
```
|
70
|
+
|
71
|
+
### info_command.py
|
72
|
+
|
73
|
+
```python
|
74
|
+
from mcp_proxy_adapter.commands.base import Command
|
75
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
76
|
+
|
77
|
+
class InfoCommand(Command):
|
78
|
+
"""Info command that returns project information."""
|
79
|
+
|
80
|
+
name = "info"
|
81
|
+
|
82
|
+
def execute(self) -> CommandResult:
|
83
|
+
return CommandResult(
|
84
|
+
success=True,
|
85
|
+
data={
|
86
|
+
"project": "myproject",
|
87
|
+
"version": "1.0.0",
|
88
|
+
"description": "Example project with custom commands"
|
89
|
+
}
|
90
|
+
)
|
91
|
+
|
92
|
+
@classmethod
|
93
|
+
def get_param_info(cls) -> dict:
|
94
|
+
return {}
|
95
|
+
```
|
96
|
+
|
97
|
+
## Запуск
|
98
|
+
|
99
|
+
```bash
|
100
|
+
python main.py
|
101
|
+
```
|
102
|
+
|
103
|
+
При запуске сервис автоматически обнаружит команды из пакета `myproject.commands` благодаря настройке `discovery_path` в конфигурации.
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# Custom Project Example with Commands
|
2
|
+
|
3
|
+
This example shows how to create your own project with commands and configure `discovery_path` for their automatic discovery.
|
4
|
+
|
5
|
+
## Project Structure
|
6
|
+
|
7
|
+
```
|
8
|
+
myproject/
|
9
|
+
├── config.json
|
10
|
+
├── main.py
|
11
|
+
├── myproject/
|
12
|
+
│ ├── __init__.py
|
13
|
+
│ └── commands/
|
14
|
+
│ ├── __init__.py
|
15
|
+
│ ├── echo_command.py
|
16
|
+
│ └── info_command.py
|
17
|
+
└── README.md
|
18
|
+
```
|
19
|
+
|
20
|
+
## Configuration
|
21
|
+
|
22
|
+
In the `config.json` file, specify the path to our commands:
|
23
|
+
|
24
|
+
```json
|
25
|
+
{
|
26
|
+
"server": {
|
27
|
+
"host": "127.0.0.1",
|
28
|
+
"port": 8001,
|
29
|
+
"debug": true,
|
30
|
+
"log_level": "DEBUG"
|
31
|
+
},
|
32
|
+
"logging": {
|
33
|
+
"level": "DEBUG",
|
34
|
+
"log_dir": "./logs",
|
35
|
+
"log_file": "myproject.log"
|
36
|
+
},
|
37
|
+
"commands": {
|
38
|
+
"auto_discovery": true,
|
39
|
+
"discovery_path": "myproject.commands"
|
40
|
+
}
|
41
|
+
}
|
42
|
+
```
|
43
|
+
|
44
|
+
## Commands
|
45
|
+
|
46
|
+
### echo_command.py
|
47
|
+
|
48
|
+
```python
|
49
|
+
from mcp_proxy_adapter.commands.base import Command
|
50
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
51
|
+
|
52
|
+
class EchoCommand(Command):
|
53
|
+
"""Echo command that returns the input text."""
|
54
|
+
|
55
|
+
name = "echo"
|
56
|
+
|
57
|
+
def execute(self, text: str) -> CommandResult:
|
58
|
+
return CommandResult(success=True, data={"echo": text})
|
59
|
+
|
60
|
+
@classmethod
|
61
|
+
def get_param_info(cls) -> dict:
|
62
|
+
return {
|
63
|
+
"text": {
|
64
|
+
"type": "string",
|
65
|
+
"description": "Text to echo",
|
66
|
+
"required": True
|
67
|
+
}
|
68
|
+
}
|
69
|
+
```
|
70
|
+
|
71
|
+
### info_command.py
|
72
|
+
|
73
|
+
```python
|
74
|
+
from mcp_proxy_adapter.commands.base import Command
|
75
|
+
from mcp_proxy_adapter.commands.result import CommandResult
|
76
|
+
|
77
|
+
class InfoCommand(Command):
|
78
|
+
"""Info command that returns project information."""
|
79
|
+
|
80
|
+
name = "info"
|
81
|
+
|
82
|
+
def execute(self) -> CommandResult:
|
83
|
+
return CommandResult(
|
84
|
+
success=True,
|
85
|
+
data={
|
86
|
+
"project": "myproject",
|
87
|
+
"version": "1.0.0",
|
88
|
+
"description": "Example project with custom commands"
|
89
|
+
}
|
90
|
+
)
|
91
|
+
|
92
|
+
@classmethod
|
93
|
+
def get_param_info(cls) -> dict:
|
94
|
+
return {}
|
95
|
+
```
|
96
|
+
|
97
|
+
## Running
|
98
|
+
|
99
|
+
```bash
|
100
|
+
python main.py
|
101
|
+
```
|
102
|
+
|
103
|
+
When starting, the service will automatically discover commands from the `myproject.commands` package thanks to the `discovery_path` configuration setting.
|