mcp-proxy-adapter 6.4.12__py3-none-any.whl → 6.4.14__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.
Files changed (23) hide show
  1. mcp_proxy_adapter/core/app_factory.py +105 -32
  2. mcp_proxy_adapter/core/mtls_server.py +314 -0
  3. mcp_proxy_adapter/core/server_engine.py +1 -0
  4. mcp_proxy_adapter/examples/run_full_test_suite.py +1 -1
  5. mcp_proxy_adapter/version.py +1 -1
  6. {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/METADATA +1 -1
  7. {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/RECORD +10 -22
  8. mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +0 -9
  9. mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +0 -4
  10. mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +0 -4
  11. mcp_proxy_adapter/examples/examples/basic_framework/main.py +0 -52
  12. mcp_proxy_adapter/examples/examples/full_application/__init__.py +0 -13
  13. mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +0 -7
  14. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +0 -92
  15. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +0 -97
  16. mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +0 -7
  17. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +0 -88
  18. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +0 -81
  19. mcp_proxy_adapter/examples/examples/full_application/main.py +0 -61
  20. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +0 -188
  21. {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/WHEEL +0 -0
  22. {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/entry_points.txt +0 -0
  23. {mcp_proxy_adapter-6.4.12.dist-info → mcp_proxy_adapter-6.4.14.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,7 @@ mcp_proxy_adapter/config.py,sha256=-7iVS0mUWWKNeao7nqTAFlUD6FcMwRlDkchN7OwYsr0,2
4
4
  mcp_proxy_adapter/custom_openapi.py,sha256=yLle4CntYK9wpivgn9NflZyJhy-YNrmWjJzt0ai5nP0,14672
5
5
  mcp_proxy_adapter/main.py,sha256=idp3KUR7CT7kTXLVPvvclJlNnt8d_HYl8_jY98uknmo,4677
6
6
  mcp_proxy_adapter/openapi.py,sha256=2UZOI09ZDRJuBYBjKbMyb2U4uASszoCMD5o_4ktRpvg,13480
7
- mcp_proxy_adapter/version.py,sha256=AuC4X8tE_ZN_ehkTZYFXK_D9dCGtOUNdRena2LNA8Zk,75
7
+ mcp_proxy_adapter/version.py,sha256=H2e7NMkKo93HZNRJKiAyNvfQ_4LVFzPu6Git9F7B7ZM,75
8
8
  mcp_proxy_adapter/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  mcp_proxy_adapter/api/app.py,sha256=UQ7_m-LbUzKuuPJPxS_69ahANUQ5rnPwoddQ2MMXNkg,33941
10
10
  mcp_proxy_adapter/api/handlers.py,sha256=iyFGoEuUS1wxbV1ELA0zmaxIyQR7j4zw-4MrD-uIO6E,8294
@@ -53,7 +53,7 @@ mcp_proxy_adapter/commands/token_management_command.py,sha256=tCVjhWqAQ3KhcwSsZU
53
53
  mcp_proxy_adapter/commands/transport_management_command.py,sha256=HEnUyL4S014jheyBwO90u9gnzk0qxBlOJdC_0Sxhq9E,4585
54
54
  mcp_proxy_adapter/commands/unload_command.py,sha256=6CUM9B9c-mNxw7uvt2vcvZSnxMySfoMT5UmDhzNXq38,4984
55
55
  mcp_proxy_adapter/core/__init__.py,sha256=3yt0CFZdsIG8Ln4bg-r4ISYzipm3ZUAxTn0twYTs9FI,867
56
- mcp_proxy_adapter/core/app_factory.py,sha256=oMVEmQIrk6GYyi78rpAzQSH6K0Fq9auv_ByjaQWDUww,19539
56
+ mcp_proxy_adapter/core/app_factory.py,sha256=T-GS0aCINLTKVGumLGJdWWweik0sTW7hFFGxqcDXwD0,21438
57
57
  mcp_proxy_adapter/core/app_runner.py,sha256=1t9p_UkWb1IvZDTD7FOCRMNSpOSgtNeHM3i7PP7x6xc,10605
58
58
  mcp_proxy_adapter/core/auth_validator.py,sha256=q8TNkdolvP-gM6Bvecc6nrVG9al5J31pocdwhguhTBk,19742
59
59
  mcp_proxy_adapter/core/certificate_utils.py,sha256=yeDwi-j42CxK_g-r5_ragGFY_HdSgDfTWHVUjDHF6nI,38480
@@ -67,6 +67,7 @@ mcp_proxy_adapter/core/errors.py,sha256=UNEfdmK0zPGJrWH1zUMRjHIJMcoVDcBO4w8xxKHB
67
67
  mcp_proxy_adapter/core/logging.py,sha256=gNI6vfPQC7jrUtVu6NeDsmU72JPlrRRBhtJipL1eVrI,9560
68
68
  mcp_proxy_adapter/core/mtls_asgi.py,sha256=tvk0P9024s18dcCHY9AaQIecT4ojOTv21EuQWXwooU0,5200
69
69
  mcp_proxy_adapter/core/mtls_asgi_app.py,sha256=DT_fTUH1RkvBa3ThbyCyNb-XUHyCb4DqaKA1gcZC6z4,6538
70
+ mcp_proxy_adapter/core/mtls_server.py,sha256=_hj6QWuExKX2LRohYvjPGFC2qTutS7ObegpEc09QijM,10117
70
71
  mcp_proxy_adapter/core/protocol_manager.py,sha256=3sWOAiMniQY5nu9CHkitIOGN4CXH28hOTwY92D0yasM,15268
71
72
  mcp_proxy_adapter/core/proxy_client.py,sha256=CB6KBhV3vH2GU5nZ27VZ_xlNbYTAU_tnYFrkuK5He58,6094
72
73
  mcp_proxy_adapter/core/proxy_registration.py,sha256=qgNtdYPXZ6F1oXRXIXCICCL9NYkOteGrTVPQAI8P5mg,31483
@@ -75,7 +76,7 @@ mcp_proxy_adapter/core/security_adapter.py,sha256=MAtNthsp7Qj4-oLFzSi7Pr3vWQbWS_
75
76
  mcp_proxy_adapter/core/security_factory.py,sha256=M-1McwUOmuV7Eo-m_P2undtJVNK_KIjDx8o_uRY8rLo,8005
76
77
  mcp_proxy_adapter/core/security_integration.py,sha256=oGYoJKrPoOqw262j3daeG8B6ro4pOGYMWmZR_hsTQOc,16881
77
78
  mcp_proxy_adapter/core/server_adapter.py,sha256=qKTHdVAwoCUHEF4G3EEUG7JTfLS49ucYMQSkQAz_F4E,9601
78
- mcp_proxy_adapter/core/server_engine.py,sha256=S91QvY4PPLfllz4Bfv4gDXb4ErIQhHp1FP9Uez_d-mU,9456
79
+ mcp_proxy_adapter/core/server_engine.py,sha256=qmxdkBv-YsQsvxVVQ-_xiAyDshxtnrKBquPJoUjo2fw,9471
79
80
  mcp_proxy_adapter/core/settings.py,sha256=D6cF4R_5gJ0XFGxzXUIzeqe-_muu6HL561TAei9wwZ0,10521
80
81
  mcp_proxy_adapter/core/ssl_utils.py,sha256=Rjl79d5LdhDzxiMtaIRd9OFh0hTeRANItYFXk-7c5pA,9498
81
82
  mcp_proxy_adapter/core/transport_manager.py,sha256=eJbGa3gDVFUBFUzMK5KEmpbUDXOOShtzszUIEf7Jk0A,9292
@@ -93,7 +94,7 @@ mcp_proxy_adapter/examples/generate_certificates_and_tokens.py,sha256=hUCoJH3fy5
93
94
  mcp_proxy_adapter/examples/generate_test_configs.py,sha256=FWg_QFJAWinI1lw05RccX4_VbhsCBEKPpZA6I9v6KAs,14379
94
95
  mcp_proxy_adapter/examples/proxy_registration_example.py,sha256=vemRhftnjbiOBCJkmtDGqlWQ8syTG0a8755GCOnaQsg,12503
95
96
  mcp_proxy_adapter/examples/run_example.py,sha256=yp-a6HIrSk3ddQmbn0KkuKwErId0aNfj028TE6U-zmY,2626
96
- mcp_proxy_adapter/examples/run_full_test_suite.py,sha256=2VvcnDy2EkufxLHFFbgchNZ5Z7UjPuCI1wFEMvmehUk,19948
97
+ mcp_proxy_adapter/examples/run_full_test_suite.py,sha256=G8G9AgVKadA5-J4khahybS9i_xCbhp0Xl8kAaSCoA7U,19935
97
98
  mcp_proxy_adapter/examples/run_proxy_server.py,sha256=SBLSSY2F_VEBQD3MsCE_Pa9xFE6Sszr3vHdE9QOEN4Y,5242
98
99
  mcp_proxy_adapter/examples/run_security_tests.py,sha256=0vjaUdWC-rLyviQuNxM3PtfiU9TzSRuxGxWMehrFA_w,23311
99
100
  mcp_proxy_adapter/examples/run_security_tests_fixed.py,sha256=2BKMT0_-FhmcZA73hdQOt2XR7Cgb9Sq8qBI88BkwAAA,10934
@@ -108,19 +109,6 @@ mcp_proxy_adapter/examples/basic_framework/main.py,sha256=XdGrD_52hhCVHwqx4XmfVm
108
109
  mcp_proxy_adapter/examples/basic_framework/commands/__init__.py,sha256=_VQNLUEdsxUG-4yt9BZI_vtOxHAdGG0OUSsP6Wj-Vz4,76
109
110
  mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py,sha256=IE_EIXMnkdXuakZn7wLD9kBFyfDF5lYi56ejgiBeb-A,70
110
111
  mcp_proxy_adapter/examples/commands/__init__.py,sha256=zvY_OpH_B1bVc_khrNIl6O8vqCw1FH6gGMAsJAkGWGY,170
111
- mcp_proxy_adapter/examples/examples/basic_framework/__init__.py,sha256=4aYD--R6hy9n9CUxj7Osb9HcdVUMJ6_cfpu4ujkbCwI,345
112
- mcp_proxy_adapter/examples/examples/basic_framework/main.py,sha256=Vg8LMaXPsHUccfZlNWA2XVaJ1t7FDCK8nPshAVJAhxU,1776
113
- mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py,sha256=_VQNLUEdsxUG-4yt9BZI_vtOxHAdGG0OUSsP6Wj-Vz4,76
114
- mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py,sha256=IE_EIXMnkdXuakZn7wLD9kBFyfDF5lYi56ejgiBeb-A,70
115
- mcp_proxy_adapter/examples/examples/full_application/__init__.py,sha256=xGiPYhRAzs1Fh9wA8HoowV-Gg9QMLaMZn-OamExq1TI,320
116
- mcp_proxy_adapter/examples/examples/full_application/main.py,sha256=i5o9prWKQv6EXUyNZQERlfah9q-GoloKMQHOVqnQIgo,1991
117
- mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py,sha256=Kt_WAsG61HLTMkKQ1mQqjvlX9I4TcfwYq0NaRR9HKvM,6179
118
- mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py,sha256=yQHxVSFkAyFLUOdk42QOebUODPlQV9IbydPgF3UKsGM,217
119
- mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py,sha256=H7FPJmVJNWT61rPWxep06-7hsYRt8XYBUSBiwqpBurU,3096
120
- mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py,sha256=DFTqVnIDt6nBdZ27-vD_f1X2cFcDInVQiCEq9ltw4lA,3428
121
- mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py,sha256=ORG4cL8cSXEMmZ0CEPz75OVuwg54pdDm2GIBpP4dtcs,200
122
- mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py,sha256=vcMHakKOt9pvJDZ6XfgvcYJfrrxg-RnIC8wX6LPqKvA,3500
123
- mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py,sha256=P5KjODcVPier-nxjWWpG7yO7ppSjSx-6BJ9FxArD-ps,2988
124
112
  mcp_proxy_adapter/examples/full_application/__init__.py,sha256=xGiPYhRAzs1Fh9wA8HoowV-Gg9QMLaMZn-OamExq1TI,320
125
113
  mcp_proxy_adapter/examples/full_application/main.py,sha256=ogL3Bil_5puGnwvMh3YNOjrW76FIzzoggKEp-04HSfo,7855
126
114
  mcp_proxy_adapter/examples/full_application/proxy_endpoints.py,sha256=Kt_WAsG61HLTMkKQ1mQqjvlX9I4TcfwYq0NaRR9HKvM,6179
@@ -133,8 +121,8 @@ mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py,sha25
133
121
  mcp_proxy_adapter/examples/scripts/config_generator.py,sha256=SKFlRRCE_pEHGbfjDuzfKpvV2DMwG6lRfK90uJwRlJM,33410
134
122
  mcp_proxy_adapter/examples/scripts/create_certificates_simple.py,sha256=yCWdUIhMSDPwoPhuLR9rhPdf7jLN5hCjzNfYYgVyHnw,27769
135
123
  mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py,sha256=hUCoJH3fy5WeR_YMHj-_W0mR0ZKUWqewH4FVN3yWyrM,17972
136
- mcp_proxy_adapter-6.4.12.dist-info/METADATA,sha256=EBFcB6piku6QastRpuAjeDW-VwZDfYuvvd2F22uR2w4,6087
137
- mcp_proxy_adapter-6.4.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
138
- mcp_proxy_adapter-6.4.12.dist-info/entry_points.txt,sha256=J3eV6ID0lt_VSp4lIdIgBFTqLCThgObNNxRCbyfiMHw,70
139
- mcp_proxy_adapter-6.4.12.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
140
- mcp_proxy_adapter-6.4.12.dist-info/RECORD,,
124
+ mcp_proxy_adapter-6.4.14.dist-info/METADATA,sha256=hpdPu6cT_Znpcu4hbYyi1pFD05pUVnGT4x3TAzgKzvY,6087
125
+ mcp_proxy_adapter-6.4.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
126
+ mcp_proxy_adapter-6.4.14.dist-info/entry_points.txt,sha256=J3eV6ID0lt_VSp4lIdIgBFTqLCThgObNNxRCbyfiMHw,70
127
+ mcp_proxy_adapter-6.4.14.dist-info/top_level.txt,sha256=JZT7vPLBYrtroX-ij68JBhJYbjDdghcV-DFySRy-Nnw,18
128
+ mcp_proxy_adapter-6.4.14.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- """Basic Framework Example.
2
-
3
- This example demonstrates the fundamental usage of MCP Proxy Adapter
4
- with minimal configuration and basic command registration.
5
-
6
- Note: This package provides a basic example of MCP Proxy Adapter usage.
7
- The main application is created dynamically in main.py and not exported
8
- as a global variable for this example.
9
- """
@@ -1,4 +0,0 @@
1
- """Basic Framework Commands.
2
-
3
- Commands for the basic framework example.
4
- """
@@ -1,4 +0,0 @@
1
- """Basic Framework Hooks.
2
-
3
- Hooks for the basic framework example.
4
- """
@@ -1,52 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Basic Framework Example
4
- This example demonstrates the basic usage of the MCP Proxy Adapter framework
5
- with minimal configuration and built-in commands.
6
- Author: Vasiliy Zdanovskiy
7
- email: vasilyvz@gmail.com
8
- """
9
- import sys
10
- import argparse
11
- import asyncio
12
- from pathlib import Path
13
-
14
- # Add the framework to the path
15
- sys.path.insert(0, str(Path(__file__).parent.parent.parent))
16
- from mcp_proxy_adapter.core.app_factory import create_and_run_server
17
-
18
-
19
- def main():
20
- """Main entry point for the basic framework example."""
21
- parser = argparse.ArgumentParser(description="Basic Framework Example")
22
- parser.add_argument(
23
- "--config", "-c", required=True, help="Path to configuration file"
24
- )
25
- parser.add_argument("--host", help="Server host")
26
- parser.add_argument("--port", type=int, help="Server port")
27
- parser.add_argument("--debug", action="store_true", help="Enable debug mode")
28
- args = parser.parse_args()
29
- # Override configuration if specified
30
- config_overrides = {}
31
- if args.host:
32
- config_overrides["host"] = args.host
33
- if args.port:
34
- config_overrides["port"] = args.port
35
- if args.debug:
36
- config_overrides["debug"] = True
37
- print(f"🚀 Starting Basic Framework Example")
38
- print(f"📋 Configuration: {args.config}")
39
- print("=" * 50)
40
- # Use the factory method to create and run the server
41
- asyncio.run(create_and_run_server(
42
- config_path=args.config,
43
- title="Basic Framework Example",
44
- description="Basic MCP Proxy Adapter with minimal configuration",
45
- version="1.0.0",
46
- host=config_overrides.get("host", "0.0.0.0"),
47
- log_level="debug" if config_overrides.get("debug", False) else "info",
48
- ))
49
-
50
-
51
- if __name__ == "__main__":
52
- main()
@@ -1,13 +0,0 @@
1
- """Full Application Example.
2
-
3
- This example demonstrates advanced usage of MCP Proxy Adapter including:
4
- - Proxy registration endpoints
5
- - Custom command hooks
6
- - Advanced security configurations
7
- - Role-based access control
8
- """
9
-
10
- from .main import get_app
11
-
12
- app = get_app()
13
- from .proxy_endpoints import router as proxy_router
@@ -1,7 +0,0 @@
1
- """Full Application Commands.
2
-
3
- Custom command implementations for the full application example.
4
- """
5
-
6
- from .custom_echo_command import CustomEchoCommand
7
- from .dynamic_calculator_command import DynamicCalculatorCommand
@@ -1,92 +0,0 @@
1
- """
2
- Custom Echo Command
3
- This module demonstrates a custom command implementation for the full application example.
4
- Author: Vasiliy Zdanovskiy
5
- email: vasilyvz@gmail.com
6
- """
7
-
8
- from typing import Dict, Any, Optional
9
- from mcp_proxy_adapter.commands.base import BaseCommand
10
- from mcp_proxy_adapter.commands.result import CommandResult
11
-
12
-
13
- class CustomEchoResult(CommandResult):
14
- """Result class for custom echo command."""
15
-
16
- def __init__(self, message: str, timestamp: str, echo_count: int):
17
- self.message = message
18
- self.timestamp = timestamp
19
- self.echo_count = echo_count
20
-
21
- def to_dict(self) -> Dict[str, Any]:
22
- """Convert result to dictionary."""
23
- return {
24
- "message": self.message,
25
- "timestamp": self.timestamp,
26
- "echo_count": self.echo_count,
27
- "command_type": "custom_echo",
28
- }
29
-
30
- def get_schema(self) -> Dict[str, Any]:
31
- """Get result schema."""
32
- return {
33
- "type": "object",
34
- "properties": {
35
- "message": {"type": "string", "description": "Echoed message"},
36
- "timestamp": {"type": "string", "description": "Timestamp of echo"},
37
- "echo_count": {"type": "integer", "description": "Number of echoes"},
38
- "command_type": {"type": "string", "description": "Command type"},
39
- },
40
- "required": ["message", "timestamp", "echo_count", "command_type"],
41
- }
42
-
43
-
44
- class CustomEchoCommand(BaseCommand):
45
- """Custom echo command implementation."""
46
-
47
- def __init__(self):
48
- super().__init__()
49
- self.echo_count = 0
50
-
51
- def get_name(self) -> str:
52
- """Get command name."""
53
- return "custom_echo"
54
-
55
- def get_description(self) -> str:
56
- """Get command description."""
57
- return "Custom echo command with enhanced features"
58
-
59
- def get_schema(self) -> Dict[str, Any]:
60
- """Get command schema."""
61
- return {
62
- "type": "object",
63
- "properties": {
64
- "message": {
65
- "type": "string",
66
- "description": "Message to echo",
67
- "default": "Hello from custom echo!",
68
- },
69
- "repeat": {
70
- "type": "integer",
71
- "description": "Number of times to repeat",
72
- "default": 1,
73
- "minimum": 1,
74
- "maximum": 10,
75
- },
76
- },
77
- "required": ["message"],
78
- }
79
-
80
- async def execute(self, params: Dict[str, Any]) -> CustomEchoResult:
81
- """Execute the custom echo command."""
82
- message = params.get("message", "Hello from custom echo!")
83
- repeat = min(max(params.get("repeat", 1), 1), 10)
84
- self.echo_count += 1
85
- from datetime import datetime
86
-
87
- timestamp = datetime.now().isoformat()
88
- # Repeat the message
89
- echoed_message = " ".join([message] * repeat)
90
- return CustomEchoResult(
91
- message=echoed_message, timestamp=timestamp, echo_count=self.echo_count
92
- )
@@ -1,97 +0,0 @@
1
- """
2
- Dynamic Calculator Command
3
- This module demonstrates a dynamically loaded command implementation for the full application example.
4
- Author: Vasiliy Zdanovskiy
5
- email: vasilyvz@gmail.com
6
- """
7
-
8
- from typing import Dict, Any, Optional
9
- from mcp_proxy_adapter.commands.base import BaseCommand
10
- from mcp_proxy_adapter.commands.result import CommandResult
11
-
12
-
13
- class CalculatorResult(CommandResult):
14
- """Result class for calculator command."""
15
-
16
- def __init__(self, operation: str, result: float, expression: str):
17
- self.operation = operation
18
- self.result = result
19
- self.expression = expression
20
-
21
- def to_dict(self) -> Dict[str, Any]:
22
- """Convert result to dictionary."""
23
- return {
24
- "operation": self.operation,
25
- "result": self.result,
26
- "expression": self.expression,
27
- "command_type": "dynamic_calculator",
28
- }
29
-
30
- def get_schema(self) -> Dict[str, Any]:
31
- """Get result schema."""
32
- return {
33
- "type": "object",
34
- "properties": {
35
- "operation": {
36
- "type": "string",
37
- "description": "Mathematical operation",
38
- },
39
- "result": {"type": "number", "description": "Calculation result"},
40
- "expression": {"type": "string", "description": "Full expression"},
41
- "command_type": {"type": "string", "description": "Command type"},
42
- },
43
- "required": ["operation", "result", "expression", "command_type"],
44
- }
45
-
46
-
47
- class DynamicCalculatorCommand(BaseCommand):
48
- """Dynamic calculator command implementation."""
49
-
50
- def get_name(self) -> str:
51
- """Get command name."""
52
- return "dynamic_calculator"
53
-
54
- def get_description(self) -> str:
55
- """Get command description."""
56
- return "Dynamic calculator with basic mathematical operations"
57
-
58
- def get_schema(self) -> Dict[str, Any]:
59
- """Get command schema."""
60
- return {
61
- "type": "object",
62
- "properties": {
63
- "operation": {
64
- "type": "string",
65
- "description": "Mathematical operation (add, subtract, multiply, divide)",
66
- "enum": ["add", "subtract", "multiply", "divide"],
67
- },
68
- "a": {"type": "number", "description": "First number"},
69
- "b": {"type": "number", "description": "Second number"},
70
- },
71
- "required": ["operation", "a", "b"],
72
- }
73
-
74
- async def execute(self, params: Dict[str, Any]) -> CalculatorResult:
75
- """Execute the calculator command."""
76
- operation = params.get("operation")
77
- a = params.get("a")
78
- b = params.get("b")
79
- if operation == "add":
80
- result = a + b
81
- expression = f"{a} + {b}"
82
- elif operation == "subtract":
83
- result = a - b
84
- expression = f"{a} - {b}"
85
- elif operation == "multiply":
86
- result = a * b
87
- expression = f"{a} * {b}"
88
- elif operation == "divide":
89
- if b == 0:
90
- raise ValueError("Division by zero is not allowed")
91
- result = a / b
92
- expression = f"{a} / {b}"
93
- else:
94
- raise ValueError(f"Unknown operation: {operation}")
95
- return CalculatorResult(
96
- operation=operation, result=result, expression=expression
97
- )
@@ -1,7 +0,0 @@
1
- """Full Application Hooks.
2
-
3
- Application and command hooks for the full application example.
4
- """
5
-
6
- from .application_hooks import ApplicationHooks
7
- from .builtin_command_hooks import BuiltinCommandHooks
@@ -1,88 +0,0 @@
1
- """
2
- Application Hooks
3
- This module demonstrates application-level hooks in the full application example.
4
- Author: Vasiliy Zdanovskiy
5
- email: vasilyvz@gmail.com
6
- """
7
-
8
- import logging
9
- from typing import Dict, Any, Optional
10
- from datetime import datetime
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
-
15
- class ApplicationHooks:
16
- """Application-level hooks."""
17
-
18
- @staticmethod
19
- def on_startup():
20
- """Hook executed on application startup."""
21
- logger.info("🚀 Application startup hook executed")
22
- # Initialize application-specific resources
23
- logger.info("📊 Initializing application metrics")
24
- logger.info("🔐 Loading security configurations")
25
- logger.info("📝 Setting up logging")
26
-
27
- @staticmethod
28
- def on_shutdown():
29
- """Hook executed on application shutdown."""
30
- logger.info("🛑 Application shutdown hook executed")
31
- # Cleanup application resources
32
- logger.info("🧹 Cleaning up resources")
33
- logger.info("💾 Saving application state")
34
- logger.info("📊 Finalizing metrics")
35
-
36
- @staticmethod
37
- def before_request(request_data: Dict[str, Any]) -> Dict[str, Any]:
38
- """Hook executed before processing any request."""
39
- logger.info(f"🔧 Application hook: before_request with data: {request_data}")
40
- # Add request metadata
41
- request_data["app_metadata"] = {
42
- "request_id": f"req_{datetime.now().timestamp()}",
43
- "timestamp": datetime.now().isoformat(),
44
- "application": "full_application_example",
45
- }
46
- return request_data
47
-
48
- @staticmethod
49
- def after_request(result: Dict[str, Any]) -> Dict[str, Any]:
50
- """Hook executed after processing any request."""
51
- logger.info(f"🔧 Application hook: after_request with result: {result}")
52
- # Add response metadata
53
- result["app_response_metadata"] = {
54
- "processed_at": datetime.now().isoformat(),
55
- "application": "full_application_example",
56
- "version": "1.0.0",
57
- }
58
- return result
59
-
60
- @staticmethod
61
- def on_error(error: Exception, context: Dict[str, Any]):
62
- """Hook executed when an error occurs."""
63
- logger.error(f"🔧 Application hook: on_error - {error} in context: {context}")
64
- # Log error details
65
- logger.error(f"Error type: {type(error).__name__}")
66
- logger.error(f"Error message: {str(error)}")
67
- logger.error(f"Context: {context}")
68
-
69
- @staticmethod
70
- def on_command_registered(command_name: str, command_info: Dict[str, Any]):
71
- """Hook executed when a command is registered."""
72
- logger.info(f"🔧 Application hook: on_command_registered - {command_name}")
73
- logger.info(f"Command info: {command_info}")
74
- # Track registered commands
75
- logger.info(f"📝 Command '{command_name}' registered successfully")
76
-
77
- @staticmethod
78
- def on_command_executed(command_name: str, execution_time: float, success: bool):
79
- """Hook executed when a command is executed."""
80
- logger.info(f"🔧 Application hook: on_command_executed - {command_name}")
81
- logger.info(f"Execution time: {execution_time}s, Success: {success}")
82
- # Track command execution metrics
83
- if success:
84
- logger.info(
85
- f"✅ Command '{command_name}' executed successfully in {execution_time}s"
86
- )
87
- else:
88
- logger.warning(f"⚠️ Command '{command_name}' failed after {execution_time}s")
@@ -1,81 +0,0 @@
1
- """
2
- Built-in Command Hooks
3
- This module demonstrates hooks for built-in commands in the full application example.
4
- Author: Vasiliy Zdanovskiy
5
- email: vasilyvz@gmail.com
6
- """
7
-
8
- import logging
9
- from typing import Dict, Any, Optional
10
- from datetime import datetime
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
-
15
- class BuiltinCommandHooks:
16
- """Hooks for built-in commands."""
17
-
18
- @staticmethod
19
- def before_echo_command(params: Dict[str, Any]) -> Dict[str, Any]:
20
- """Hook executed before echo command."""
21
- logger.info(f"🔧 Built-in hook: before_echo_command with params: {params}")
22
- # Add timestamp to message
23
- if "message" in params:
24
- timestamp = datetime.now().isoformat()
25
- params["message"] = f"[{timestamp}] {params['message']}"
26
- return params
27
-
28
- @staticmethod
29
- def after_echo_command(result: Dict[str, Any]) -> Dict[str, Any]:
30
- """Hook executed after echo command."""
31
- logger.info(f"🔧 Built-in hook: after_echo_command with result: {result}")
32
- # Add hook metadata
33
- result["hook_metadata"] = {
34
- "hook_type": "builtin_after_echo",
35
- "timestamp": datetime.now().isoformat(),
36
- "processed": True,
37
- }
38
- return result
39
-
40
- @staticmethod
41
- def before_health_command(params: Dict[str, Any]) -> Dict[str, Any]:
42
- """Hook executed before health command."""
43
- logger.info(f"🔧 Built-in hook: before_health_command with params: {params}")
44
- # Add custom health check parameters
45
- params["include_detailed_info"] = True
46
- params["check_dependencies"] = True
47
- return params
48
-
49
- @staticmethod
50
- def after_health_command(result: Dict[str, Any]) -> Dict[str, Any]:
51
- """Hook executed after health command."""
52
- logger.info(f"🔧 Built-in hook: after_health_command with result: {result}")
53
- # Add custom health metrics
54
- if "status" in result and result["status"] == "healthy":
55
- result["custom_metrics"] = {
56
- "uptime": "24h",
57
- "memory_usage": "45%",
58
- "cpu_usage": "12%",
59
- }
60
- return result
61
-
62
- @staticmethod
63
- def before_config_command(params: Dict[str, Any]) -> Dict[str, Any]:
64
- """Hook executed before config command."""
65
- logger.info(f"🔧 Built-in hook: before_config_command with params: {params}")
66
- # Add configuration validation
67
- params["validate_config"] = True
68
- params["include_secrets"] = False
69
- return params
70
-
71
- @staticmethod
72
- def after_config_command(result: Dict[str, Any]) -> Dict[str, Any]:
73
- """Hook executed after config command."""
74
- logger.info(f"🔧 Built-in hook: after_config_command with result: {result}")
75
- # Add configuration metadata
76
- result["config_metadata"] = {
77
- "last_modified": datetime.now().isoformat(),
78
- "version": "1.0.0",
79
- "environment": "development",
80
- }
81
- return result
@@ -1,61 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Full Application Example
4
- This is a complete application that demonstrates all features of MCP Proxy Adapter framework:
5
- - Built-in commands
6
- - Custom commands
7
- - Dynamically loaded commands
8
- - Built-in command hooks
9
- - Application hooks
10
- Author: Vasiliy Zdanovskiy
11
- email: vasilyvz@gmail.com
12
- """
13
- import sys
14
- import argparse
15
- import asyncio
16
- import logging
17
- from pathlib import Path
18
-
19
- # Add the framework to the path
20
- sys.path.insert(0, str(Path(__file__).parent.parent.parent))
21
- from mcp_proxy_adapter.core.app_factory import create_and_run_server
22
-
23
-
24
- def main():
25
- """Main entry point for the full application example."""
26
- parser = argparse.ArgumentParser(description="Full Application Example")
27
- parser.add_argument(
28
- "--config", "-c", required=True, help="Path to configuration file"
29
- )
30
- parser.add_argument("--host", help="Server host")
31
- parser.add_argument("--port", type=int, help="Server port")
32
- parser.add_argument("--debug", action="store_true", help="Enable debug mode")
33
- args = parser.parse_args()
34
-
35
- # Override configuration if specified
36
- config_overrides = {}
37
- if args.host:
38
- config_overrides["host"] = args.host
39
- if args.port:
40
- config_overrides["port"] = args.port
41
- if args.debug:
42
- config_overrides["debug"] = True
43
-
44
- print(f"🚀 Starting Full Application Example")
45
- print(f"📋 Configuration: {args.config}")
46
- print(f"🔧 Features: Built-in commands, Custom commands, Dynamic commands, Hooks, Proxy endpoints")
47
- print("=" * 60)
48
-
49
- # Use the factory method to create and run the server
50
- asyncio.run(create_and_run_server(
51
- config_path=args.config,
52
- title="Full Application Example",
53
- description="Complete MCP Proxy Adapter with all features",
54
- version="1.0.0",
55
- host=config_overrides.get("host", "0.0.0.0"),
56
- log_level="debug" if config_overrides.get("debug", False) else "info",
57
- ))
58
-
59
-
60
- if __name__ == "__main__":
61
- main()