mcp-proxy-adapter 2.0.1__py3-none-any.whl → 6.9.50__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.
Potentially problematic release.
This version of mcp-proxy-adapter might be problematic. Click here for more details.
- mcp_proxy_adapter/__init__.py +47 -0
- mcp_proxy_adapter/__main__.py +13 -0
- mcp_proxy_adapter/api/__init__.py +0 -0
- mcp_proxy_adapter/api/app.py +66 -0
- mcp_proxy_adapter/api/core/__init__.py +18 -0
- mcp_proxy_adapter/api/core/app_factory.py +400 -0
- mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
- mcp_proxy_adapter/api/core/registration_context.py +356 -0
- mcp_proxy_adapter/api/core/registration_manager.py +307 -0
- mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
- mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
- mcp_proxy_adapter/api/handlers.py +181 -0
- mcp_proxy_adapter/api/middleware/__init__.py +21 -0
- mcp_proxy_adapter/api/middleware/base.py +54 -0
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
- mcp_proxy_adapter/api/middleware/factory.py +147 -0
- mcp_proxy_adapter/api/middleware/logging.py +31 -0
- mcp_proxy_adapter/api/middleware/performance.py +51 -0
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
- mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
- mcp_proxy_adapter/api/openapi/__init__.py +21 -0
- mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
- mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
- mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
- mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
- mcp_proxy_adapter/api/schemas.py +270 -0
- mcp_proxy_adapter/api/tool_integration.py +131 -0
- mcp_proxy_adapter/api/tools.py +163 -0
- mcp_proxy_adapter/cli/__init__.py +12 -0
- mcp_proxy_adapter/cli/commands/__init__.py +15 -0
- mcp_proxy_adapter/cli/commands/client.py +100 -0
- mcp_proxy_adapter/cli/commands/config_generate.py +105 -0
- mcp_proxy_adapter/cli/commands/config_validate.py +94 -0
- mcp_proxy_adapter/cli/commands/generate.py +259 -0
- mcp_proxy_adapter/cli/commands/server.py +174 -0
- mcp_proxy_adapter/cli/commands/sets.py +132 -0
- mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
- mcp_proxy_adapter/cli/examples/__init__.py +8 -0
- mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
- mcp_proxy_adapter/cli/examples/https_token.py +96 -0
- mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
- mcp_proxy_adapter/cli/main.py +63 -0
- mcp_proxy_adapter/cli/parser.py +338 -0
- mcp_proxy_adapter/cli/validators.py +231 -0
- mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
- mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
- mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
- mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
- mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
- mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
- mcp_proxy_adapter/client/proxy.py +123 -0
- mcp_proxy_adapter/commands/__init__.py +66 -0
- mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
- mcp_proxy_adapter/commands/base.py +389 -0
- mcp_proxy_adapter/commands/builtin_commands.py +30 -0
- mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
- mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
- mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
- mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
- mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
- mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
- mcp_proxy_adapter/commands/catalog_manager.py +97 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
- mcp_proxy_adapter/commands/command_registry.py +298 -0
- mcp_proxy_adapter/commands/config_command.py +102 -0
- mcp_proxy_adapter/commands/dependency_container.py +40 -0
- mcp_proxy_adapter/commands/dependency_manager.py +143 -0
- mcp_proxy_adapter/commands/echo_command.py +48 -0
- mcp_proxy_adapter/commands/health_command.py +142 -0
- mcp_proxy_adapter/commands/help_command.py +175 -0
- mcp_proxy_adapter/commands/hooks.py +172 -0
- mcp_proxy_adapter/commands/key_management_command.py +484 -0
- mcp_proxy_adapter/commands/load_command.py +123 -0
- mcp_proxy_adapter/commands/plugins_command.py +246 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
- mcp_proxy_adapter/commands/queue_commands.py +750 -0
- mcp_proxy_adapter/commands/registration_status_command.py +76 -0
- mcp_proxy_adapter/commands/registry/__init__.py +18 -0
- mcp_proxy_adapter/commands/registry/command_info.py +103 -0
- mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
- mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
- mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
- mcp_proxy_adapter/commands/reload_command.py +136 -0
- mcp_proxy_adapter/commands/result.py +157 -0
- mcp_proxy_adapter/commands/role_test_command.py +99 -0
- mcp_proxy_adapter/commands/roles_management_command.py +502 -0
- mcp_proxy_adapter/commands/security_command.py +472 -0
- mcp_proxy_adapter/commands/settings_command.py +113 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
- mcp_proxy_adapter/commands/token_management_command.py +500 -0
- mcp_proxy_adapter/commands/transport_management_command.py +129 -0
- mcp_proxy_adapter/commands/unload_command.py +92 -0
- mcp_proxy_adapter/config.py +32 -0
- mcp_proxy_adapter/core/__init__.py +8 -0
- mcp_proxy_adapter/core/app_factory.py +560 -0
- mcp_proxy_adapter/core/app_runner.py +318 -0
- mcp_proxy_adapter/core/auth_validator.py +508 -0
- mcp_proxy_adapter/core/certificate/__init__.py +20 -0
- mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
- mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
- mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/certificate/certificate_validator.py +481 -0
- mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
- mcp_proxy_adapter/core/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/client.py +608 -0
- mcp_proxy_adapter/core/client_manager.py +271 -0
- mcp_proxy_adapter/core/client_security.py +411 -0
- mcp_proxy_adapter/core/config/__init__.py +18 -0
- mcp_proxy_adapter/core/config/config.py +237 -0
- mcp_proxy_adapter/core/config/config_factory.py +22 -0
- mcp_proxy_adapter/core/config/config_loader.py +66 -0
- mcp_proxy_adapter/core/config/feature_manager.py +31 -0
- mcp_proxy_adapter/core/config/simple_config.py +204 -0
- mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
- mcp_proxy_adapter/core/config/simple_config_validator.py +476 -0
- mcp_proxy_adapter/core/config_converter.py +252 -0
- mcp_proxy_adapter/core/config_validator.py +211 -0
- mcp_proxy_adapter/core/crl_utils.py +362 -0
- mcp_proxy_adapter/core/errors.py +276 -0
- mcp_proxy_adapter/core/job_manager.py +54 -0
- mcp_proxy_adapter/core/logging.py +250 -0
- mcp_proxy_adapter/core/mtls_asgi.py +140 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/mtls_proxy.py +229 -0
- mcp_proxy_adapter/core/mtls_server.py +154 -0
- mcp_proxy_adapter/core/protocol_manager.py +232 -0
- mcp_proxy_adapter/core/proxy/__init__.py +19 -0
- mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
- mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
- mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
- mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
- mcp_proxy_adapter/core/proxy_client.py +184 -0
- mcp_proxy_adapter/core/proxy_registration.py +80 -0
- mcp_proxy_adapter/core/role_utils.py +103 -0
- mcp_proxy_adapter/core/security_adapter.py +343 -0
- mcp_proxy_adapter/core/security_factory.py +96 -0
- mcp_proxy_adapter/core/security_integration.py +342 -0
- mcp_proxy_adapter/core/server_adapter.py +251 -0
- mcp_proxy_adapter/core/server_engine.py +217 -0
- mcp_proxy_adapter/core/settings.py +260 -0
- mcp_proxy_adapter/core/signal_handler.py +107 -0
- mcp_proxy_adapter/core/ssl_utils.py +161 -0
- mcp_proxy_adapter/core/transport_manager.py +153 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
- mcp_proxy_adapter/core/utils.py +101 -0
- mcp_proxy_adapter/core/validation/__init__.py +21 -0
- mcp_proxy_adapter/core/validation/config_validator.py +219 -0
- mcp_proxy_adapter/core/validation/file_validator.py +131 -0
- mcp_proxy_adapter/core/validation/protocol_validator.py +205 -0
- mcp_proxy_adapter/core/validation/security_validator.py +140 -0
- mcp_proxy_adapter/core/validation/validation_result.py +27 -0
- mcp_proxy_adapter/custom_openapi.py +58 -0
- mcp_proxy_adapter/examples/__init__.py +16 -0
- mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
- mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
- mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
- mcp_proxy_adapter/examples/check_config.py +413 -0
- mcp_proxy_adapter/examples/client_usage_example.py +164 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/config_builder.py +234 -0
- mcp_proxy_adapter/examples/config_cli.py +282 -0
- mcp_proxy_adapter/examples/create_test_configs.py +174 -0
- mcp_proxy_adapter/examples/debug_request_state.py +130 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
- mcp_proxy_adapter/examples/demo_client.py +287 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
- mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
- mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
- mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
- mcp_proxy_adapter/examples/full_application/main.py +311 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -0
- mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
- mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
- mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
- mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
- mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
- mcp_proxy_adapter/examples/generate_config.py +502 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
- mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
- mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
- mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
- mcp_proxy_adapter/examples/queue_server_example.py +85 -0
- mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
- mcp_proxy_adapter/examples/required_certificates.py +208 -0
- mcp_proxy_adapter/examples/run_example.py +77 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
- mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
- mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
- mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
- mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
- mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
- mcp_proxy_adapter/examples/security_test_client.py +72 -0
- mcp_proxy_adapter/examples/setup/__init__.py +24 -0
- mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
- mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
- mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
- mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
- mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
- mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
- mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
- mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
- mcp_proxy_adapter/examples/test_config.py +205 -0
- mcp_proxy_adapter/examples/test_config_builder.py +110 -0
- mcp_proxy_adapter/examples/test_examples.py +308 -0
- mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
- mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
- mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
- mcp_proxy_adapter/examples/universal_client.py +674 -0
- mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
- mcp_proxy_adapter/integrations/__init__.py +25 -0
- mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
- mcp_proxy_adapter/main.py +311 -0
- mcp_proxy_adapter/openapi.py +375 -0
- mcp_proxy_adapter/schemas/base_schema.json +114 -0
- mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
- mcp_proxy_adapter/schemas/roles.json +37 -0
- mcp_proxy_adapter/schemas/roles_schema.json +162 -0
- mcp_proxy_adapter/version.py +5 -0
- mcp_proxy_adapter-6.9.50.dist-info/METADATA +1088 -0
- mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
- {mcp_proxy_adapter-2.0.1.dist-info → mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
- mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
- mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
- adapters/__init__.py +0 -16
- analyzers/__init__.py +0 -14
- analyzers/docstring_analyzer.py +0 -199
- analyzers/type_analyzer.py +0 -151
- cli/__init__.py +0 -12
- cli/__main__.py +0 -79
- cli/command_runner.py +0 -233
- dispatchers/__init__.py +0 -14
- dispatchers/base_dispatcher.py +0 -85
- dispatchers/json_rpc_dispatcher.py +0 -198
- generators/__init__.py +0 -14
- generators/endpoint_generator.py +0 -172
- generators/openapi_generator.py +0 -254
- generators/rest_api_generator.py +0 -207
- mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
- mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
- mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
- mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
- openapi_schema/__init__.py +0 -38
- openapi_schema/command_registry.py +0 -312
- openapi_schema/rest_schema.py +0 -510
- openapi_schema/rpc_generator.py +0 -307
- openapi_schema/rpc_schema.py +0 -416
- validators/__init__.py +0 -14
- validators/base_validator.py +0 -23
- validators/docstring_validator.py +0 -75
- validators/metadata_validator.py +0 -76
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Queue Integration Example for MCP Proxy Adapter.
|
|
3
|
+
|
|
4
|
+
This example demonstrates how to use the queuemgr integration
|
|
5
|
+
with mcp_proxy_adapter for managing background jobs.
|
|
6
|
+
|
|
7
|
+
Author: Vasiliy Zdanovskiy
|
|
8
|
+
email: vasilyvz@gmail.com
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import json
|
|
13
|
+
import time
|
|
14
|
+
|
|
15
|
+
from mcp_proxy_adapter.api.app import create_app
|
|
16
|
+
from mcp_proxy_adapter.commands.command_registry import registry
|
|
17
|
+
from mcp_proxy_adapter.commands.queue_commands import (
|
|
18
|
+
QueueAddJobCommand,
|
|
19
|
+
QueueStartJobCommand,
|
|
20
|
+
QueueStopJobCommand,
|
|
21
|
+
QueueDeleteJobCommand,
|
|
22
|
+
QueueGetJobStatusCommand,
|
|
23
|
+
QueueListJobsCommand,
|
|
24
|
+
QueueHealthCommand,
|
|
25
|
+
)
|
|
26
|
+
init_global_queue_manager,
|
|
27
|
+
shutdown_global_queue_manager,
|
|
28
|
+
QueueManagerIntegration,
|
|
29
|
+
queue_manager_context,
|
|
30
|
+
QueueJobBase,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
async def setup_queue_commands():
|
|
35
|
+
"""Setup queue management commands."""
|
|
36
|
+
print("🔧 Setting up queue management commands...")
|
|
37
|
+
|
|
38
|
+
# Register queue commands
|
|
39
|
+
registry.register(QueueAddJobCommand())
|
|
40
|
+
registry.register(QueueStartJobCommand())
|
|
41
|
+
registry.register(QueueStopJobCommand())
|
|
42
|
+
registry.register(QueueDeleteJobCommand())
|
|
43
|
+
registry.register(QueueGetJobStatusCommand())
|
|
44
|
+
registry.register(QueueListJobsCommand())
|
|
45
|
+
registry.register(QueueHealthCommand())
|
|
46
|
+
|
|
47
|
+
print("✅ Queue commands registered")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def demo_queue_operations():
|
|
51
|
+
"""Demonstrate queue operations with long-running jobs."""
|
|
52
|
+
print("\n🚀 Demonstrating queue operations with long-running jobs...")
|
|
53
|
+
|
|
54
|
+
# Initialize queue manager
|
|
55
|
+
queue_manager = await init_global_queue_manager(
|
|
56
|
+
registry_path="demo_queue_registry.jsonl",
|
|
57
|
+
shutdown_timeout=30.0,
|
|
58
|
+
max_concurrent_jobs=5
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
# 1. Add various types of jobs
|
|
63
|
+
print("\n1️⃣ Adding jobs to queue...")
|
|
64
|
+
|
|
65
|
+
# Quick data processing job
|
|
66
|
+
data_job_result = await queue_manager.add_job(
|
|
67
|
+
DataProcessingJob,
|
|
68
|
+
"data_job_1",
|
|
69
|
+
{
|
|
70
|
+
"data": {"key1": "value1", "key2": "value2"},
|
|
71
|
+
"operation": "process"
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
print(f"✅ Added data processing job: {data_job_result.job_id}")
|
|
75
|
+
|
|
76
|
+
# Long-running job (15 seconds)
|
|
77
|
+
long_job_result = await queue_manager.add_job(
|
|
78
|
+
LongRunningJob,
|
|
79
|
+
"long_job_1",
|
|
80
|
+
{
|
|
81
|
+
"duration": 15,
|
|
82
|
+
"task_type": "data_analysis"
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
print(f"✅ Added long-running job: {long_job_result.job_id}")
|
|
86
|
+
|
|
87
|
+
# Batch processing job
|
|
88
|
+
batch_job_result = await queue_manager.add_job(
|
|
89
|
+
BatchProcessingJob,
|
|
90
|
+
"batch_job_1",
|
|
91
|
+
{
|
|
92
|
+
"batch_size": 50,
|
|
93
|
+
"items": [f"item_{i}" for i in range(50)]
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
print(f"✅ Added batch processing job: {batch_job_result.job_id}")
|
|
97
|
+
|
|
98
|
+
# File download job
|
|
99
|
+
download_job_result = await queue_manager.add_job(
|
|
100
|
+
FileDownloadJob,
|
|
101
|
+
"download_job_1",
|
|
102
|
+
{
|
|
103
|
+
"url": "https://example.com/large_file.zip",
|
|
104
|
+
"file_size": 5 * 1024 * 1024 # 5MB
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
print(f"✅ Added file download job: {download_job_result.job_id}")
|
|
108
|
+
|
|
109
|
+
# 2. Start jobs
|
|
110
|
+
print("\n2️⃣ Starting jobs...")
|
|
111
|
+
|
|
112
|
+
await queue_manager.start_job("data_job_1")
|
|
113
|
+
print("✅ Started data processing job")
|
|
114
|
+
|
|
115
|
+
await queue_manager.start_job("long_job_1")
|
|
116
|
+
print("✅ Started long-running job")
|
|
117
|
+
|
|
118
|
+
await queue_manager.start_job("batch_job_1")
|
|
119
|
+
print("✅ Started batch processing job")
|
|
120
|
+
|
|
121
|
+
await queue_manager.start_job("download_job_1")
|
|
122
|
+
print("✅ Started file download job")
|
|
123
|
+
|
|
124
|
+
# 3. Monitor job status with detailed progress
|
|
125
|
+
print("\n3️⃣ Monitoring job status with progress...")
|
|
126
|
+
|
|
127
|
+
for i in range(20): # Monitor for 20 iterations
|
|
128
|
+
print(f"\n--- Status check {i+1} ---")
|
|
129
|
+
|
|
130
|
+
# Check individual job status
|
|
131
|
+
jobs_to_check = ["data_job_1", "long_job_1", "batch_job_1", "download_job_1"]
|
|
132
|
+
|
|
133
|
+
for job_id in jobs_to_check:
|
|
134
|
+
try:
|
|
135
|
+
status = await queue_manager.get_job_status(job_id)
|
|
136
|
+
print(f"{job_id}: {status.status} (progress: {status.progress}%) - {status.description}")
|
|
137
|
+
|
|
138
|
+
if status.error:
|
|
139
|
+
print(f" ❌ Error: {status.error}")
|
|
140
|
+
except Exception as e:
|
|
141
|
+
print(f"{job_id}: Error getting status - {e}")
|
|
142
|
+
|
|
143
|
+
# List all jobs summary
|
|
144
|
+
all_jobs = await queue_manager.list_jobs()
|
|
145
|
+
running_jobs = [job for job in all_jobs if job.status == "running"]
|
|
146
|
+
completed_jobs = [job for job in all_jobs if job.status == "completed"]
|
|
147
|
+
failed_jobs = [job for job in all_jobs if job.status == "failed"]
|
|
148
|
+
|
|
149
|
+
print(f"📊 Summary: {len(running_jobs)} running, {len(completed_jobs)} completed, {len(failed_jobs)} failed")
|
|
150
|
+
|
|
151
|
+
# Check if all jobs are done
|
|
152
|
+
if len(running_jobs) == 0:
|
|
153
|
+
print("✅ All jobs completed!")
|
|
154
|
+
break
|
|
155
|
+
|
|
156
|
+
await asyncio.sleep(1) # Check every second
|
|
157
|
+
|
|
158
|
+
# 4. Get detailed job results
|
|
159
|
+
print("\n4️⃣ Getting detailed job results...")
|
|
160
|
+
|
|
161
|
+
for job_id in ["data_job_1", "long_job_1", "batch_job_1", "download_job_1"]:
|
|
162
|
+
try:
|
|
163
|
+
status = await queue_manager.get_job_status(job_id)
|
|
164
|
+
print(f"\n📋 {job_id} Results:")
|
|
165
|
+
print(f" Status: {status.status}")
|
|
166
|
+
print(f" Progress: {status.progress}%")
|
|
167
|
+
print(f" Description: {status.description}")
|
|
168
|
+
|
|
169
|
+
if status.result:
|
|
170
|
+
print(f" Result: {json.dumps(status.result, indent=4)}")
|
|
171
|
+
|
|
172
|
+
if status.error:
|
|
173
|
+
print(f" Error: {status.error}")
|
|
174
|
+
|
|
175
|
+
except Exception as e:
|
|
176
|
+
print(f"❌ Error getting results for {job_id}: {e}")
|
|
177
|
+
|
|
178
|
+
# 5. Check queue health
|
|
179
|
+
print("\n5️⃣ Checking queue health...")
|
|
180
|
+
|
|
181
|
+
health = await queue_manager.get_queue_health()
|
|
182
|
+
print(f"Queue health: {json.dumps(health, indent=2)}")
|
|
183
|
+
|
|
184
|
+
finally:
|
|
185
|
+
# Cleanup
|
|
186
|
+
print("\n🧹 Cleaning up...")
|
|
187
|
+
await shutdown_global_queue_manager()
|
|
188
|
+
print("✅ Queue manager stopped")
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
async def demo_with_context_manager():
|
|
192
|
+
"""Demonstrate using queue manager with context manager."""
|
|
193
|
+
print("\n🔄 Demonstrating context manager usage...")
|
|
194
|
+
|
|
195
|
+
async with queue_manager_context(
|
|
196
|
+
registry_path="demo_context_registry.jsonl",
|
|
197
|
+
shutdown_timeout=30.0,
|
|
198
|
+
max_concurrent_jobs=3
|
|
199
|
+
) as queue_manager:
|
|
200
|
+
|
|
201
|
+
# Add and start a job
|
|
202
|
+
result = await queue_manager.add_job(
|
|
203
|
+
CustomJob,
|
|
204
|
+
"context_job_1",
|
|
205
|
+
{"custom_data": {"test": "value"}}
|
|
206
|
+
)
|
|
207
|
+
print(f"✅ Added job: {result.job_id}")
|
|
208
|
+
|
|
209
|
+
await queue_manager.start_job("context_job_1")
|
|
210
|
+
print("✅ Started job")
|
|
211
|
+
|
|
212
|
+
# Wait a bit
|
|
213
|
+
await asyncio.sleep(2)
|
|
214
|
+
|
|
215
|
+
# Check status
|
|
216
|
+
status = await queue_manager.get_job_status("context_job_1")
|
|
217
|
+
print(f"Job status: {status.status}")
|
|
218
|
+
|
|
219
|
+
if status.result:
|
|
220
|
+
print(f"Job result: {json.dumps(status.result, indent=2)}")
|
|
221
|
+
|
|
222
|
+
print("✅ Context manager cleanup completed")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def create_mcp_app_with_queue():
|
|
226
|
+
"""Create MCP application with queue integration."""
|
|
227
|
+
app = create_app()
|
|
228
|
+
|
|
229
|
+
# Setup startup and shutdown events
|
|
230
|
+
@app.on_event("startup")
|
|
231
|
+
async def startup_event():
|
|
232
|
+
await setup_queue_commands()
|
|
233
|
+
await init_global_queue_manager()
|
|
234
|
+
print("✅ MCP application with queue integration started")
|
|
235
|
+
|
|
236
|
+
@app.on_event("shutdown")
|
|
237
|
+
async def shutdown_event():
|
|
238
|
+
await shutdown_global_queue_manager()
|
|
239
|
+
print("✅ MCP application with queue integration stopped")
|
|
240
|
+
|
|
241
|
+
return app
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
async def main():
|
|
245
|
+
"""Main function to run the queue integration example."""
|
|
246
|
+
print("🚀 MCP Proxy Adapter Queue Integration Example")
|
|
247
|
+
print("=" * 50)
|
|
248
|
+
|
|
249
|
+
# Demo 1: Basic queue operations
|
|
250
|
+
await demo_queue_operations()
|
|
251
|
+
|
|
252
|
+
# Demo 2: Context manager usage
|
|
253
|
+
await demo_with_context_manager()
|
|
254
|
+
|
|
255
|
+
print("\n🎉 Queue integration example completed!")
|
|
256
|
+
print("\n📋 Available queue commands:")
|
|
257
|
+
print(" - queue_add_job: Add a job to the queue")
|
|
258
|
+
print(" - queue_start_job: Start a job")
|
|
259
|
+
print(" - queue_stop_job: Stop a job")
|
|
260
|
+
print(" - queue_delete_job: Delete a job")
|
|
261
|
+
print(" - queue_get_job_status: Get job status")
|
|
262
|
+
print(" - queue_list_jobs: List all jobs")
|
|
263
|
+
print(" - queue_health: Check queue health")
|
|
264
|
+
|
|
265
|
+
print("\n📝 Example JSON-RPC calls:")
|
|
266
|
+
print("1. Add a data processing job:")
|
|
267
|
+
print(json.dumps({
|
|
268
|
+
"jsonrpc": "2.0",
|
|
269
|
+
"method": "queue_add_job",
|
|
270
|
+
"params": {
|
|
271
|
+
"job_type": "data_processing",
|
|
272
|
+
"job_id": "my_data_job",
|
|
273
|
+
"params": {
|
|
274
|
+
"data": {"key": "value"},
|
|
275
|
+
"operation": "process"
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"id": 1
|
|
279
|
+
}, indent=2))
|
|
280
|
+
|
|
281
|
+
print("\n2. Start the job:")
|
|
282
|
+
print(json.dumps({
|
|
283
|
+
"jsonrpc": "2.0",
|
|
284
|
+
"method": "queue_start_job",
|
|
285
|
+
"params": {
|
|
286
|
+
"job_id": "my_data_job"
|
|
287
|
+
},
|
|
288
|
+
"id": 2
|
|
289
|
+
}, indent=2))
|
|
290
|
+
|
|
291
|
+
print("\n3. Check job status:")
|
|
292
|
+
print(json.dumps({
|
|
293
|
+
"jsonrpc": "2.0",
|
|
294
|
+
"method": "queue_get_job_status",
|
|
295
|
+
"params": {
|
|
296
|
+
"job_id": "my_data_job"
|
|
297
|
+
},
|
|
298
|
+
"id": 3
|
|
299
|
+
}, indent=2))
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
# Example job classes
|
|
303
|
+
class DataProcessingJob(QueueJobBase):
|
|
304
|
+
"""Example data processing job."""
|
|
305
|
+
|
|
306
|
+
def run(self) -> None:
|
|
307
|
+
"""Execute data processing job."""
|
|
308
|
+
import time
|
|
309
|
+
import json
|
|
310
|
+
|
|
311
|
+
self.logger.info(f"DataProcessingJob {self.job_id}: Starting data processing")
|
|
312
|
+
|
|
313
|
+
data = self.mcp_params.get("data", {})
|
|
314
|
+
operation = self.mcp_params.get("operation", "process")
|
|
315
|
+
|
|
316
|
+
# Simulate processing
|
|
317
|
+
time.sleep(2)
|
|
318
|
+
|
|
319
|
+
result = {
|
|
320
|
+
"job_id": self.job_id,
|
|
321
|
+
"operation": operation,
|
|
322
|
+
"processed_at": time.time(),
|
|
323
|
+
"data_size": len(json.dumps(data)),
|
|
324
|
+
"status": "completed"
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
self.set_mcp_result(result)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
class FileOperationJob(QueueJobBase):
|
|
331
|
+
"""Example file operation job."""
|
|
332
|
+
|
|
333
|
+
def run(self) -> None:
|
|
334
|
+
"""Execute file operation job."""
|
|
335
|
+
import os
|
|
336
|
+
import time
|
|
337
|
+
|
|
338
|
+
self.logger.info(f"FileOperationJob {self.job_id}: Starting file operation")
|
|
339
|
+
|
|
340
|
+
file_path = self.mcp_params.get("file_path", "")
|
|
341
|
+
operation = self.mcp_params.get("operation", "read")
|
|
342
|
+
|
|
343
|
+
try:
|
|
344
|
+
if operation == "read" and os.path.exists(file_path):
|
|
345
|
+
with open(file_path, "r") as f:
|
|
346
|
+
content = f.read()
|
|
347
|
+
|
|
348
|
+
result = {
|
|
349
|
+
"job_id": self.job_id,
|
|
350
|
+
"operation": operation,
|
|
351
|
+
"file_path": file_path,
|
|
352
|
+
"file_size": len(content),
|
|
353
|
+
"status": "completed"
|
|
354
|
+
}
|
|
355
|
+
else:
|
|
356
|
+
result = {
|
|
357
|
+
"job_id": self.job_id,
|
|
358
|
+
"operation": operation,
|
|
359
|
+
"file_path": file_path,
|
|
360
|
+
"error": f"File not found or invalid operation: {operation}",
|
|
361
|
+
"status": "failed"
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
self.set_mcp_result(result, result["status"])
|
|
365
|
+
|
|
366
|
+
except Exception as e:
|
|
367
|
+
self.set_mcp_error(f"File operation failed: {str(e)}")
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
class ApiCallJob(QueueJobBase):
|
|
371
|
+
"""Example API call job."""
|
|
372
|
+
|
|
373
|
+
def run(self) -> None:
|
|
374
|
+
"""Execute API call job."""
|
|
375
|
+
import requests
|
|
376
|
+
import time
|
|
377
|
+
|
|
378
|
+
self.logger.info(f"ApiCallJob {self.job_id}: Starting API call")
|
|
379
|
+
|
|
380
|
+
url = self.mcp_params.get("url", "")
|
|
381
|
+
method = self.mcp_params.get("method", "GET")
|
|
382
|
+
headers = self.mcp_params.get("headers", {})
|
|
383
|
+
timeout = self.mcp_params.get("timeout", 30)
|
|
384
|
+
|
|
385
|
+
try:
|
|
386
|
+
response = requests.request(
|
|
387
|
+
method=method,
|
|
388
|
+
url=url,
|
|
389
|
+
headers=headers,
|
|
390
|
+
timeout=timeout
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
result = {
|
|
394
|
+
"job_id": self.job_id,
|
|
395
|
+
"url": url,
|
|
396
|
+
"method": method,
|
|
397
|
+
"status_code": response.status_code,
|
|
398
|
+
"response_size": len(response.content),
|
|
399
|
+
"status": "completed"
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
self.set_mcp_result(result)
|
|
403
|
+
|
|
404
|
+
except Exception as e:
|
|
405
|
+
self.set_mcp_error(f"API call failed: {str(e)}")
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
class CustomJob(QueueJobBase):
|
|
409
|
+
"""Example custom job."""
|
|
410
|
+
|
|
411
|
+
def run(self) -> None:
|
|
412
|
+
"""Execute custom job."""
|
|
413
|
+
import time
|
|
414
|
+
|
|
415
|
+
self.logger.info(f"CustomJob {self.job_id}: Starting custom job")
|
|
416
|
+
|
|
417
|
+
custom_data = self.mcp_params.get("custom_data", {})
|
|
418
|
+
|
|
419
|
+
# Simulate work
|
|
420
|
+
time.sleep(1)
|
|
421
|
+
|
|
422
|
+
result = {
|
|
423
|
+
"job_id": self.job_id,
|
|
424
|
+
"custom_data": custom_data,
|
|
425
|
+
"processed_at": time.time(),
|
|
426
|
+
"status": "completed"
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
self.set_mcp_result(result)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
class LongRunningJob(QueueJobBase):
|
|
433
|
+
"""Example long-running job with progress updates."""
|
|
434
|
+
|
|
435
|
+
def run(self) -> None:
|
|
436
|
+
"""Execute long-running job with progress updates."""
|
|
437
|
+
import time
|
|
438
|
+
import random
|
|
439
|
+
|
|
440
|
+
self.logger.info(f"LongRunningJob {self.job_id}: Starting long-running job")
|
|
441
|
+
|
|
442
|
+
duration = self.mcp_params.get("duration", 10) # Default 10 seconds
|
|
443
|
+
task_type = self.mcp_params.get("task_type", "data_processing")
|
|
444
|
+
|
|
445
|
+
self.set_status("running")
|
|
446
|
+
self.set_description(f"Processing {task_type} task...")
|
|
447
|
+
|
|
448
|
+
# Simulate long-running work with progress updates
|
|
449
|
+
for i in range(duration):
|
|
450
|
+
# Update progress
|
|
451
|
+
progress = int((i + 1) / duration * 100)
|
|
452
|
+
self.set_progress(progress)
|
|
453
|
+
self.set_description(f"Processing {task_type} task... {progress}% complete")
|
|
454
|
+
|
|
455
|
+
# Simulate work
|
|
456
|
+
time.sleep(1)
|
|
457
|
+
|
|
458
|
+
# Simulate occasional errors (5% chance)
|
|
459
|
+
if random.random() < 0.05:
|
|
460
|
+
self.set_mcp_error(f"Simulated error at {progress}%", "failed")
|
|
461
|
+
return
|
|
462
|
+
|
|
463
|
+
# Complete successfully
|
|
464
|
+
result = {
|
|
465
|
+
"job_id": self.job_id,
|
|
466
|
+
"task_type": task_type,
|
|
467
|
+
"duration": duration,
|
|
468
|
+
"completed_at": time.time(),
|
|
469
|
+
"status": "completed"
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
self.set_mcp_result(result)
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
class BatchProcessingJob(QueueJobBase):
|
|
476
|
+
"""Example batch processing job."""
|
|
477
|
+
|
|
478
|
+
def run(self) -> None:
|
|
479
|
+
"""Execute batch processing job."""
|
|
480
|
+
import time
|
|
481
|
+
import random
|
|
482
|
+
|
|
483
|
+
self.logger.info(f"BatchProcessingJob {self.job_id}: Starting batch processing")
|
|
484
|
+
|
|
485
|
+
batch_size = self.mcp_params.get("batch_size", 100)
|
|
486
|
+
items = self.mcp_params.get("items", [])
|
|
487
|
+
|
|
488
|
+
self.set_status("running")
|
|
489
|
+
self.set_description(f"Processing batch of {len(items)} items...")
|
|
490
|
+
|
|
491
|
+
processed_items = []
|
|
492
|
+
|
|
493
|
+
for i, item in enumerate(items):
|
|
494
|
+
# Update progress
|
|
495
|
+
progress = int((i + 1) / len(items) * 100)
|
|
496
|
+
self.set_progress(progress)
|
|
497
|
+
self.set_description(f"Processing item {i+1}/{len(items)}... {progress}% complete")
|
|
498
|
+
|
|
499
|
+
# Simulate processing each item
|
|
500
|
+
time.sleep(0.1) # 100ms per item
|
|
501
|
+
|
|
502
|
+
# Simulate processing result
|
|
503
|
+
processed_item = {
|
|
504
|
+
"original": item,
|
|
505
|
+
"processed": f"processed_{item}",
|
|
506
|
+
"timestamp": time.time()
|
|
507
|
+
}
|
|
508
|
+
processed_items.append(processed_item)
|
|
509
|
+
|
|
510
|
+
# Simulate occasional processing errors (2% chance)
|
|
511
|
+
if random.random() < 0.02:
|
|
512
|
+
self.set_mcp_error(f"Processing failed at item {i+1}: {item}", "failed")
|
|
513
|
+
return
|
|
514
|
+
|
|
515
|
+
# Complete successfully
|
|
516
|
+
result = {
|
|
517
|
+
"job_id": self.job_id,
|
|
518
|
+
"batch_size": batch_size,
|
|
519
|
+
"processed_count": len(processed_items),
|
|
520
|
+
"processed_items": processed_items,
|
|
521
|
+
"completed_at": time.time(),
|
|
522
|
+
"status": "completed"
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
self.set_mcp_result(result)
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
class FileDownloadJob(QueueJobBase):
|
|
529
|
+
"""Example file download job with progress tracking."""
|
|
530
|
+
|
|
531
|
+
def run(self) -> None:
|
|
532
|
+
"""Execute file download job."""
|
|
533
|
+
import time
|
|
534
|
+
import random
|
|
535
|
+
|
|
536
|
+
self.logger.info(f"FileDownloadJob {self.job_id}: Starting file download")
|
|
537
|
+
|
|
538
|
+
url = self.mcp_params.get("url", "https://example.com/file.zip")
|
|
539
|
+
file_size = self.mcp_params.get("file_size", 1024 * 1024) # Default 1MB
|
|
540
|
+
|
|
541
|
+
self.set_status("running")
|
|
542
|
+
self.set_description(f"Downloading {url}...")
|
|
543
|
+
|
|
544
|
+
# Simulate download with progress updates
|
|
545
|
+
downloaded = 0
|
|
546
|
+
chunk_size = 64 * 1024 # 64KB chunks
|
|
547
|
+
|
|
548
|
+
while downloaded < file_size:
|
|
549
|
+
# Simulate download chunk
|
|
550
|
+
chunk = min(chunk_size, file_size - downloaded)
|
|
551
|
+
time.sleep(0.1) # Simulate network delay
|
|
552
|
+
|
|
553
|
+
downloaded += chunk
|
|
554
|
+
progress = int(downloaded / file_size * 100)
|
|
555
|
+
|
|
556
|
+
self.set_progress(progress)
|
|
557
|
+
self.set_description(f"Downloading {url}... {progress}% complete ({downloaded}/{file_size} bytes)")
|
|
558
|
+
|
|
559
|
+
# Simulate occasional network errors (3% chance)
|
|
560
|
+
if random.random() < 0.03:
|
|
561
|
+
self.set_mcp_error(f"Network error during download at {progress}%", "failed")
|
|
562
|
+
return
|
|
563
|
+
|
|
564
|
+
# Complete successfully
|
|
565
|
+
result = {
|
|
566
|
+
"job_id": self.job_id,
|
|
567
|
+
"url": url,
|
|
568
|
+
"file_size": file_size,
|
|
569
|
+
"downloaded_bytes": downloaded,
|
|
570
|
+
"completed_at": time.time(),
|
|
571
|
+
"status": "completed"
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
self.set_mcp_result(result)
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
if __name__ == "__main__":
|
|
578
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Queue Server Demo for MCP Proxy Adapter.
|
|
4
|
+
|
|
5
|
+
This example demonstrates how to run an MCP server with queue integration
|
|
6
|
+
using a mock queue manager for demonstration purposes.
|
|
7
|
+
|
|
8
|
+
Author: Vasiliy Zdanovskiy
|
|
9
|
+
email: vasilyvz@gmail.com
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
import uvicorn
|
|
14
|
+
from mcp_proxy_adapter.api.app import create_app
|
|
15
|
+
from mcp_proxy_adapter.commands.command_registry import registry
|
|
16
|
+
from mcp_proxy_adapter.commands.queue_commands import (
|
|
17
|
+
QueueAddJobCommand,
|
|
18
|
+
QueueStartJobCommand,
|
|
19
|
+
QueueStopJobCommand,
|
|
20
|
+
QueueDeleteJobCommand,
|
|
21
|
+
QueueGetJobStatusCommand,
|
|
22
|
+
QueueListJobsCommand,
|
|
23
|
+
QueueHealthCommand,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
async def setup_queue_commands():
|
|
28
|
+
"""Setup queue management commands."""
|
|
29
|
+
print("🔧 Setting up queue management commands...")
|
|
30
|
+
|
|
31
|
+
# Register queue commands
|
|
32
|
+
registry.register(QueueAddJobCommand())
|
|
33
|
+
registry.register(QueueStartJobCommand())
|
|
34
|
+
registry.register(QueueStopJobCommand())
|
|
35
|
+
registry.register(QueueDeleteJobCommand())
|
|
36
|
+
registry.register(QueueGetJobStatusCommand())
|
|
37
|
+
registry.register(QueueListJobsCommand())
|
|
38
|
+
registry.register(QueueHealthCommand())
|
|
39
|
+
|
|
40
|
+
print("✅ Queue commands registered")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def create_queue_server_app():
|
|
44
|
+
"""Create MCP server application with queue integration."""
|
|
45
|
+
app = create_app()
|
|
46
|
+
|
|
47
|
+
@app.on_event("startup")
|
|
48
|
+
|
|
49
|
+
@app.on_event("shutdown")
|
|
50
|
+
|
|
51
|
+
return app
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
async def main():
|
|
55
|
+
"""Main function to run the queue server."""
|
|
56
|
+
print("🚀 Starting MCP Proxy Adapter Queue Server Demo")
|
|
57
|
+
print("=" * 50)
|
|
58
|
+
|
|
59
|
+
# Create the app
|
|
60
|
+
app = create_queue_server_app()
|
|
61
|
+
|
|
62
|
+
# Run the server
|
|
63
|
+
config = uvicorn.Config(
|
|
64
|
+
app=app,
|
|
65
|
+
host="0.0.0.0",
|
|
66
|
+
port=8000,
|
|
67
|
+
log_level="info"
|
|
68
|
+
)
|
|
69
|
+
server = uvicorn.Server(config)
|
|
70
|
+
|
|
71
|
+
print("✅ MCP Queue Server started at http://localhost:8000")
|
|
72
|
+
print("📝 Example usage:")
|
|
73
|
+
print(" curl -X POST http://localhost:8000/api/jsonrpc \\")
|
|
74
|
+
print(" -H 'Content-Type: application/json' \\")
|
|
75
|
+
print(" -d '{\"jsonrpc\": \"2.0\", \"method\": \"queue_health\", \"params\": {}, \"id\": 1}'")
|
|
76
|
+
print()
|
|
77
|
+
|
|
78
|
+
await server.serve()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
if __name__ == "__main__":
|
|
82
|
+
asyncio.run(main())
|