mcp-proxy-adapter 2.1.17__py3-none-any.whl → 3.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. examples/__init__.py +19 -0
  2. examples/anti_patterns/README.md +51 -0
  3. examples/anti_patterns/__init__.py +9 -0
  4. examples/anti_patterns/bad_design/README.md +72 -0
  5. examples/anti_patterns/bad_design/global_state.py +170 -0
  6. examples/anti_patterns/bad_design/monolithic_command.py +272 -0
  7. examples/basic_example/README.md +245 -0
  8. examples/basic_example/__init__.py +8 -0
  9. examples/basic_example/commands/__init__.py +5 -0
  10. examples/basic_example/commands/echo_command.py +95 -0
  11. examples/basic_example/commands/math_command.py +151 -0
  12. examples/basic_example/commands/time_command.py +152 -0
  13. examples/basic_example/config.json +25 -0
  14. examples/basic_example/docs/EN/README.md +177 -0
  15. examples/basic_example/docs/RU/README.md +177 -0
  16. examples/basic_example/server.py +151 -0
  17. examples/basic_example/tests/conftest.py +243 -0
  18. examples/commands/echo_command.py +52 -0
  19. examples/commands/echo_result.py +65 -0
  20. examples/commands/get_date_command.py +98 -0
  21. examples/commands/new_uuid4_command.py +91 -0
  22. examples/complete_example/Dockerfile +24 -0
  23. examples/complete_example/README.md +92 -0
  24. examples/complete_example/__init__.py +8 -0
  25. examples/complete_example/commands/__init__.py +5 -0
  26. examples/complete_example/commands/system_command.py +328 -0
  27. examples/complete_example/config.json +41 -0
  28. examples/complete_example/configs/config.dev.yaml +40 -0
  29. examples/complete_example/configs/config.docker.yaml +40 -0
  30. examples/complete_example/docker-compose.yml +35 -0
  31. examples/complete_example/requirements.txt +20 -0
  32. examples/complete_example/server.py +139 -0
  33. examples/minimal_example/README.md +65 -0
  34. examples/minimal_example/__init__.py +8 -0
  35. examples/minimal_example/config.json +14 -0
  36. examples/minimal_example/main.py +136 -0
  37. examples/minimal_example/simple_server.py +163 -0
  38. examples/minimal_example/tests/conftest.py +171 -0
  39. examples/minimal_example/tests/test_hello_command.py +111 -0
  40. examples/minimal_example/tests/test_integration.py +181 -0
  41. examples/server.py +69 -0
  42. examples/simple_server.py +128 -0
  43. examples/test_server.py +134 -0
  44. examples/tool_description_example.py +82 -0
  45. mcp_proxy_adapter/__init__.py +33 -1
  46. mcp_proxy_adapter/api/__init__.py +0 -0
  47. mcp_proxy_adapter/api/app.py +391 -0
  48. mcp_proxy_adapter/api/handlers.py +229 -0
  49. mcp_proxy_adapter/api/middleware/__init__.py +49 -0
  50. mcp_proxy_adapter/api/middleware/auth.py +146 -0
  51. mcp_proxy_adapter/api/middleware/base.py +79 -0
  52. mcp_proxy_adapter/api/middleware/error_handling.py +198 -0
  53. mcp_proxy_adapter/api/middleware/logging.py +96 -0
  54. mcp_proxy_adapter/api/middleware/performance.py +83 -0
  55. mcp_proxy_adapter/api/middleware/rate_limit.py +152 -0
  56. mcp_proxy_adapter/api/schemas.py +305 -0
  57. mcp_proxy_adapter/api/tool_integration.py +223 -0
  58. mcp_proxy_adapter/api/tools.py +198 -0
  59. mcp_proxy_adapter/commands/__init__.py +19 -0
  60. mcp_proxy_adapter/commands/base.py +301 -0
  61. mcp_proxy_adapter/commands/command_registry.py +231 -0
  62. mcp_proxy_adapter/commands/config_command.py +113 -0
  63. mcp_proxy_adapter/commands/health_command.py +136 -0
  64. mcp_proxy_adapter/commands/help_command.py +193 -0
  65. mcp_proxy_adapter/commands/result.py +215 -0
  66. mcp_proxy_adapter/config.py +195 -0
  67. mcp_proxy_adapter/core/__init__.py +0 -0
  68. mcp_proxy_adapter/core/errors.py +173 -0
  69. mcp_proxy_adapter/core/logging.py +205 -0
  70. mcp_proxy_adapter/core/utils.py +138 -0
  71. mcp_proxy_adapter/custom_openapi.py +125 -0
  72. mcp_proxy_adapter/openapi.py +403 -0
  73. mcp_proxy_adapter/py.typed +0 -0
  74. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  75. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  76. mcp_proxy_adapter/tests/__init__.py +0 -0
  77. mcp_proxy_adapter/tests/api/__init__.py +3 -0
  78. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +115 -0
  79. mcp_proxy_adapter/tests/api/test_middleware.py +336 -0
  80. mcp_proxy_adapter/tests/commands/__init__.py +3 -0
  81. mcp_proxy_adapter/tests/commands/test_config_command.py +211 -0
  82. mcp_proxy_adapter/tests/commands/test_echo_command.py +127 -0
  83. mcp_proxy_adapter/tests/commands/test_help_command.py +133 -0
  84. mcp_proxy_adapter/tests/conftest.py +131 -0
  85. mcp_proxy_adapter/tests/functional/__init__.py +3 -0
  86. mcp_proxy_adapter/tests/functional/test_api.py +235 -0
  87. mcp_proxy_adapter/tests/integration/__init__.py +3 -0
  88. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +130 -0
  89. mcp_proxy_adapter/tests/integration/test_integration.py +255 -0
  90. mcp_proxy_adapter/tests/performance/__init__.py +3 -0
  91. mcp_proxy_adapter/tests/performance/test_performance.py +189 -0
  92. mcp_proxy_adapter/tests/stubs/__init__.py +10 -0
  93. mcp_proxy_adapter/tests/stubs/echo_command.py +104 -0
  94. mcp_proxy_adapter/tests/test_api_endpoints.py +271 -0
  95. mcp_proxy_adapter/tests/test_api_handlers.py +289 -0
  96. mcp_proxy_adapter/tests/test_base_command.py +123 -0
  97. mcp_proxy_adapter/tests/test_batch_requests.py +117 -0
  98. mcp_proxy_adapter/tests/test_command_registry.py +245 -0
  99. mcp_proxy_adapter/tests/test_config.py +127 -0
  100. mcp_proxy_adapter/tests/test_utils.py +65 -0
  101. mcp_proxy_adapter/tests/unit/__init__.py +3 -0
  102. mcp_proxy_adapter/tests/unit/test_base_command.py +130 -0
  103. mcp_proxy_adapter/tests/unit/test_config.py +217 -0
  104. mcp_proxy_adapter/version.py +3 -0
  105. mcp_proxy_adapter-3.0.1.dist-info/METADATA +200 -0
  106. mcp_proxy_adapter-3.0.1.dist-info/RECORD +109 -0
  107. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/top_level.txt +1 -0
  108. mcp_proxy_adapter/adapter.py +0 -697
  109. mcp_proxy_adapter/analyzers/__init__.py +0 -1
  110. mcp_proxy_adapter/analyzers/docstring_analyzer.py +0 -199
  111. mcp_proxy_adapter/analyzers/type_analyzer.py +0 -151
  112. mcp_proxy_adapter/dispatchers/__init__.py +0 -1
  113. mcp_proxy_adapter/dispatchers/base_dispatcher.py +0 -85
  114. mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py +0 -262
  115. mcp_proxy_adapter/examples/analyze_config.py +0 -141
  116. mcp_proxy_adapter/examples/basic_integration.py +0 -155
  117. mcp_proxy_adapter/examples/docstring_and_schema_example.py +0 -69
  118. mcp_proxy_adapter/examples/extension_example.py +0 -72
  119. mcp_proxy_adapter/examples/help_best_practices.py +0 -67
  120. mcp_proxy_adapter/examples/help_usage.py +0 -64
  121. mcp_proxy_adapter/examples/mcp_proxy_client.py +0 -131
  122. mcp_proxy_adapter/examples/openapi_server.py +0 -383
  123. mcp_proxy_adapter/examples/project_structure_example.py +0 -47
  124. mcp_proxy_adapter/examples/testing_example.py +0 -64
  125. mcp_proxy_adapter/models.py +0 -47
  126. mcp_proxy_adapter/registry.py +0 -439
  127. mcp_proxy_adapter/schema.py +0 -257
  128. mcp_proxy_adapter/testing_utils.py +0 -112
  129. mcp_proxy_adapter/validators/__init__.py +0 -1
  130. mcp_proxy_adapter/validators/docstring_validator.py +0 -75
  131. mcp_proxy_adapter/validators/metadata_validator.py +0 -76
  132. mcp_proxy_adapter-2.1.17.dist-info/METADATA +0 -376
  133. mcp_proxy_adapter-2.1.17.dist-info/RECORD +0 -30
  134. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/WHEEL +0 -0
  135. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,328 @@
1
+ """
2
+ System information command module.
3
+
4
+ This module contains a command that returns detailed information about the system.
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ import socket
10
+ import platform
11
+ import datetime
12
+ from typing import Dict, Any, Optional, List
13
+
14
+ import psutil
15
+ import pytz
16
+
17
+ from mcp_proxy_adapter import Command, SuccessResult
18
+
19
+
20
+ class SystemInfoResult(SuccessResult):
21
+ """
22
+ Result of system_info command.
23
+
24
+ Attributes:
25
+ system (dict): System information
26
+ cpu (dict): CPU information
27
+ memory (dict): Memory information
28
+ disk (dict): Disk information
29
+ python (dict): Python information
30
+ network (dict): Network information
31
+ time (dict): Time information
32
+ """
33
+
34
+ def __init__(
35
+ self,
36
+ system: Dict[str, Any],
37
+ cpu: Dict[str, Any],
38
+ memory: Dict[str, Any],
39
+ disk: Dict[str, Any],
40
+ python: Dict[str, Any],
41
+ network: Dict[str, Any],
42
+ time: Dict[str, Any]
43
+ ):
44
+ """
45
+ Initialize result.
46
+
47
+ Args:
48
+ system: System information
49
+ cpu: CPU information
50
+ memory: Memory information
51
+ disk: Disk information
52
+ python: Python information
53
+ network: Network information
54
+ time: Time information
55
+ """
56
+ self.system = system
57
+ self.cpu = cpu
58
+ self.memory = memory
59
+ self.disk = disk
60
+ self.python = python
61
+ self.network = network
62
+ self.time = time
63
+
64
+ def to_dict(self) -> Dict[str, Any]:
65
+ """
66
+ Convert result to dictionary.
67
+
68
+ Returns:
69
+ Dictionary representation
70
+ """
71
+ return {
72
+ "system": self.system,
73
+ "cpu": self.cpu,
74
+ "memory": self.memory,
75
+ "disk": self.disk,
76
+ "python": self.python,
77
+ "network": self.network,
78
+ "time": self.time
79
+ }
80
+
81
+ @classmethod
82
+ def get_schema(cls) -> Dict[str, Any]:
83
+ """
84
+ Get JSON schema for result.
85
+
86
+ Returns:
87
+ JSON schema
88
+ """
89
+ return {
90
+ "type": "object",
91
+ "properties": {
92
+ "system": {
93
+ "type": "object",
94
+ "description": "System information",
95
+ "properties": {
96
+ "platform": {"type": "string"},
97
+ "system": {"type": "string"},
98
+ "node": {"type": "string"},
99
+ "release": {"type": "string"},
100
+ "version": {"type": "string"},
101
+ "machine": {"type": "string"},
102
+ "processor": {"type": "string"},
103
+ "uptime": {"type": "number"}
104
+ }
105
+ },
106
+ "cpu": {
107
+ "type": "object",
108
+ "description": "CPU information",
109
+ "properties": {
110
+ "count_physical": {"type": "integer"},
111
+ "count_logical": {"type": "integer"},
112
+ "usage_percent": {"type": "number"},
113
+ "frequency": {"type": "object"}
114
+ }
115
+ },
116
+ "memory": {
117
+ "type": "object",
118
+ "description": "Memory information",
119
+ "properties": {
120
+ "total": {"type": "integer"},
121
+ "available": {"type": "integer"},
122
+ "used": {"type": "integer"},
123
+ "percent": {"type": "number"}
124
+ }
125
+ },
126
+ "disk": {
127
+ "type": "object",
128
+ "description": "Disk information",
129
+ "properties": {
130
+ "partitions": {"type": "array"},
131
+ "usage": {"type": "object"}
132
+ }
133
+ },
134
+ "python": {
135
+ "type": "object",
136
+ "description": "Python information",
137
+ "properties": {
138
+ "version": {"type": "string"},
139
+ "implementation": {"type": "string"},
140
+ "executable": {"type": "string"},
141
+ "packages": {"type": "array"}
142
+ }
143
+ },
144
+ "network": {
145
+ "type": "object",
146
+ "description": "Network information",
147
+ "properties": {
148
+ "interfaces": {"type": "array"},
149
+ "connections": {"type": "integer"}
150
+ }
151
+ },
152
+ "time": {
153
+ "type": "object",
154
+ "description": "Time information",
155
+ "properties": {
156
+ "current": {"type": "string"},
157
+ "utc": {"type": "string"},
158
+ "timezone": {"type": "string"},
159
+ "timestamp": {"type": "number"}
160
+ }
161
+ }
162
+ }
163
+ }
164
+
165
+
166
+ class SystemInfoCommand(Command):
167
+ """
168
+ Command that returns detailed system information.
169
+
170
+ This command demonstrates gathering and formatting complex system data.
171
+ """
172
+
173
+ name = "system_info"
174
+ result_class = SystemInfoResult
175
+
176
+ async def execute(
177
+ self,
178
+ include_python_packages: bool = False,
179
+ include_network_interfaces: bool = True
180
+ ) -> SystemInfoResult:
181
+ """
182
+ Execute command.
183
+
184
+ Args:
185
+ include_python_packages: Whether to include installed Python packages
186
+ include_network_interfaces: Whether to include network interfaces
187
+
188
+ Returns:
189
+ System information result
190
+ """
191
+ # Gather system information
192
+ system_info = {
193
+ "platform": platform.platform(),
194
+ "system": platform.system(),
195
+ "node": platform.node(),
196
+ "release": platform.release(),
197
+ "version": platform.version(),
198
+ "machine": platform.machine(),
199
+ "processor": platform.processor(),
200
+ "uptime": psutil.boot_time()
201
+ }
202
+
203
+ # CPU information
204
+ cpu_info = {
205
+ "count_physical": psutil.cpu_count(logical=False),
206
+ "count_logical": psutil.cpu_count(logical=True),
207
+ "usage_percent": psutil.cpu_percent(interval=0.1),
208
+ "frequency": {
209
+ "current": psutil.cpu_freq().current if psutil.cpu_freq() else 0,
210
+ "min": psutil.cpu_freq().min if psutil.cpu_freq() and psutil.cpu_freq().min else 0,
211
+ "max": psutil.cpu_freq().max if psutil.cpu_freq() and psutil.cpu_freq().max else 0
212
+ }
213
+ }
214
+
215
+ # Memory information
216
+ memory = psutil.virtual_memory()
217
+ memory_info = {
218
+ "total": memory.total,
219
+ "available": memory.available,
220
+ "used": memory.used,
221
+ "percent": memory.percent
222
+ }
223
+
224
+ # Disk information
225
+ disk_info = {
226
+ "partitions": [],
227
+ "usage": {}
228
+ }
229
+
230
+ for partition in psutil.disk_partitions():
231
+ try:
232
+ usage = psutil.disk_usage(partition.mountpoint)
233
+ disk_info["partitions"].append({
234
+ "device": partition.device,
235
+ "mountpoint": partition.mountpoint,
236
+ "fstype": partition.fstype,
237
+ "opts": partition.opts
238
+ })
239
+ disk_info["usage"][partition.mountpoint] = {
240
+ "total": usage.total,
241
+ "used": usage.used,
242
+ "free": usage.free,
243
+ "percent": usage.percent
244
+ }
245
+ except (PermissionError, FileNotFoundError):
246
+ # Some mountpoints may not be accessible
247
+ pass
248
+
249
+ # Python information
250
+ python_info = {
251
+ "version": platform.python_version(),
252
+ "implementation": platform.python_implementation(),
253
+ "executable": sys.executable,
254
+ "packages": []
255
+ }
256
+
257
+ if include_python_packages:
258
+ try:
259
+ import pkg_resources
260
+ python_info["packages"] = [
261
+ {"name": pkg.key, "version": pkg.version}
262
+ for pkg in pkg_resources.working_set
263
+ ]
264
+ except ImportError:
265
+ pass
266
+
267
+ # Network information
268
+ network_info = {
269
+ "interfaces": [],
270
+ "connections": len(psutil.net_connections())
271
+ }
272
+
273
+ if include_network_interfaces:
274
+ for interface, addresses in psutil.net_if_addrs().items():
275
+ for address in addresses:
276
+ if address.family == socket.AF_INET: # IPv4
277
+ network_info["interfaces"].append({
278
+ "interface": interface,
279
+ "address": address.address,
280
+ "netmask": address.netmask,
281
+ "broadcast": address.broadcast
282
+ })
283
+
284
+ # Time information
285
+ now = datetime.datetime.now()
286
+ utc_now = datetime.datetime.now(pytz.UTC)
287
+
288
+ time_info = {
289
+ "current": now.isoformat(),
290
+ "utc": utc_now.isoformat(),
291
+ "timezone": str(datetime.datetime.now().astimezone().tzinfo),
292
+ "timestamp": now.timestamp()
293
+ }
294
+
295
+ return SystemInfoResult(
296
+ system=system_info,
297
+ cpu=cpu_info,
298
+ memory=memory_info,
299
+ disk=disk_info,
300
+ python=python_info,
301
+ network=network_info,
302
+ time=time_info
303
+ )
304
+
305
+ @classmethod
306
+ def get_schema(cls) -> Dict[str, Any]:
307
+ """
308
+ Get JSON schema for command parameters.
309
+
310
+ Returns:
311
+ JSON schema
312
+ """
313
+ return {
314
+ "type": "object",
315
+ "properties": {
316
+ "include_python_packages": {
317
+ "type": "boolean",
318
+ "description": "Whether to include installed Python packages",
319
+ "default": False
320
+ },
321
+ "include_network_interfaces": {
322
+ "type": "boolean",
323
+ "description": "Whether to include network interfaces",
324
+ "default": True
325
+ }
326
+ },
327
+ "additionalProperties": False
328
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "service": {
3
+ "name": "Complete Example",
4
+ "version": "1.0.0",
5
+ "description": "Полный пример MCP Proxy Adapter"
6
+ },
7
+ "server": {
8
+ "host": "0.0.0.0",
9
+ "port": 8000,
10
+ "debug": false,
11
+ "log_level": "info",
12
+ "workers": 4
13
+ },
14
+ "logging": {
15
+ "level": "INFO",
16
+ "file": "logs/complete_example.log",
17
+ "rotation": {
18
+ "type": "time",
19
+ "when": "D",
20
+ "interval": 1,
21
+ "backup_count": 30
22
+ }
23
+ },
24
+ "auth": {
25
+ "enabled": false,
26
+ "token_expiration": 3600,
27
+ "secret_key": "change_this_to_a_secure_key_in_production"
28
+ },
29
+ "database": {
30
+ "url": "sqlite:///./data/database.db",
31
+ "echo": false,
32
+ "pool_size": 5,
33
+ "max_overflow": 10
34
+ },
35
+ "cache": {
36
+ "enabled": true,
37
+ "ttl": 300,
38
+ "type": "memory",
39
+ "max_size": 1000
40
+ }
41
+ }
@@ -0,0 +1,40 @@
1
+ # Development configuration for complete MCP Microservice example
2
+
3
+ # Server settings
4
+ server:
5
+ host: "localhost" # Host to bind server
6
+ port: 8000 # Port to bind server
7
+ workers: 1 # Number of worker processes
8
+ debug: true # Enable debug mode
9
+
10
+ # Logging settings
11
+ logging:
12
+ level: "DEBUG" # Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
13
+ file: "logs/complete_example.log" # Log file path
14
+ rotation:
15
+ type: "size" # Log rotation type (size, time)
16
+ max_bytes: 10485760 # Maximum log file size (10 MB)
17
+ backup_count: 5 # Number of backup files
18
+
19
+ # Command discovery settings
20
+ discovery:
21
+ enabled: true
22
+ package: "commands" # Package to discover commands
23
+
24
+ # Cache settings
25
+ cache:
26
+ enabled: true
27
+ type: "file" # Cache type (file, memory, redis)
28
+ path: "cache" # Cache directory
29
+ ttl: 300 # Default TTL in seconds
30
+
31
+ # Database settings (for db_command)
32
+ database:
33
+ enabled: false # Database is disabled in development
34
+ type: "sqlite" # Database type
35
+ path: ":memory:" # Database path (in-memory SQLite)
36
+
37
+ # File operations settings (for file_command)
38
+ files:
39
+ base_path: "." # Base path for file operations
40
+ allowed_extensions: [".txt", ".log", ".json", ".yaml"] # Allowed file extensions
@@ -0,0 +1,40 @@
1
+ # Docker configuration for complete MCP Microservice example
2
+
3
+ # Server settings
4
+ server:
5
+ host: "0.0.0.0" # Bind to all interfaces in Docker
6
+ port: 8000 # Port to bind server
7
+ workers: 2 # Number of worker processes
8
+ debug: false # Disable debug mode in production
9
+
10
+ # Logging settings
11
+ logging:
12
+ level: "INFO" # Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
13
+ file: "/app/logs/complete_example.log" # Log file path in Docker container
14
+ rotation:
15
+ type: "size" # Log rotation type (size, time)
16
+ max_bytes: 10485760 # Maximum log file size (10 MB)
17
+ backup_count: 10 # Number of backup files
18
+
19
+ # Command discovery settings
20
+ discovery:
21
+ enabled: true
22
+ package: "commands" # Package to discover commands
23
+
24
+ # Cache settings
25
+ cache:
26
+ enabled: true
27
+ type: "file" # Cache type (file, memory, redis)
28
+ path: "/app/cache" # Cache directory in Docker container
29
+ ttl: 3600 # Default TTL in seconds (1 hour)
30
+
31
+ # Database settings (for db_command)
32
+ database:
33
+ enabled: true # Enable database in Docker environment
34
+ type: "sqlite" # Database type
35
+ path: "/app/data/db.sqlite" # Database path in Docker container
36
+
37
+ # File operations settings (for file_command)
38
+ files:
39
+ base_path: "/app/data" # Base path for file operations in Docker
40
+ allowed_extensions: [".txt", ".log", ".json", ".yaml"] # Allowed file extensions
@@ -0,0 +1,35 @@
1
+ version: '3.8'
2
+
3
+ services:
4
+ mcp-proxy-adapter:
5
+ build:
6
+ context: .
7
+ dockerfile: Dockerfile
8
+ image: mcp-proxy-adapter-example:latest
9
+ container_name: mcp-proxy-adapter-example
10
+ restart: unless-stopped
11
+ ports:
12
+ - "8000:8000"
13
+ volumes:
14
+ # Mount configuration, logs, and cache from host
15
+ - ./configs:/app/configs:ro
16
+ - ./logs:/app/logs
17
+ - ./cache:/app/cache
18
+ - ./data:/app/data
19
+ environment:
20
+ - PYTHONUNBUFFERED=1
21
+ - CONFIG_PATH=/app/configs/config.docker.yaml
22
+ networks:
23
+ - smart-assistant
24
+ user: "${UID:-1000}:${GID:-1000}" # Use host user ID to avoid permission issues
25
+ healthcheck:
26
+ test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
27
+ interval: 30s
28
+ timeout: 10s
29
+ retries: 3
30
+ start_period: 10s
31
+
32
+ networks:
33
+ smart-assistant:
34
+ # Use external network if it exists, otherwise create it
35
+ external: true
@@ -0,0 +1,20 @@
1
+ # Python dependencies for MCP Microservice complete example
2
+
3
+ # Core dependencies
4
+ fastapi>=0.95.0,<1.0.0
5
+ pydantic>=2.0.0,<3.0.0
6
+ uvicorn>=0.22.0,<1.0.0
7
+ docstring-parser>=0.15,<1.0.0
8
+ typing-extensions>=4.5.0,<5.0.0
9
+ jsonrpc>=1.2.0,<2.0.0
10
+
11
+ # For system_command
12
+ psutil>=5.9.0,<6.0.0
13
+ pytz>=2023.3
14
+
15
+ # For file_command
16
+ aiofiles>=23.1.0,<24.0.0
17
+
18
+ # For db_command
19
+ aiosqlite>=0.17.0,<1.0.0
20
+ SQLAlchemy>=2.0.0,<3.0.0
@@ -0,0 +1,139 @@
1
+ """
2
+ Complete MCP Microservice example.
3
+
4
+ This example demonstrates a complete microservice application with Docker support,
5
+ environment-specific configuration, and multiple commands.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import argparse
11
+ from typing import Dict, Any
12
+ from pathlib import Path
13
+
14
+ import mcp_proxy_adapter as mcp
15
+ from mcp_proxy_adapter import MicroService
16
+ from mcp_proxy_adapter.commands.command_registry import registry
17
+ from mcp_proxy_adapter.core.logging import logger
18
+ from mcp_proxy_adapter.config import config
19
+
20
+ # Add commands directory to path for local imports
21
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
22
+
23
+
24
+ def parse_args():
25
+ """
26
+ Parse command line arguments.
27
+
28
+ Returns:
29
+ Parsed arguments
30
+ """
31
+ parser = argparse.ArgumentParser(description="MCP Microservice Example")
32
+ parser.add_argument(
33
+ "--config",
34
+ default="configs/config.dev.yaml",
35
+ help="Path to configuration file"
36
+ )
37
+ return parser.parse_args()
38
+
39
+
40
+ def ensure_directories(config_path: str):
41
+ """
42
+ Create necessary directories based on configuration.
43
+
44
+ Args:
45
+ config_path: Path to configuration file
46
+ """
47
+ # Extract base directory
48
+ base_dir = os.path.dirname(os.path.abspath(__file__))
49
+
50
+ # Create logs directory
51
+ os.makedirs(os.path.join(base_dir, "logs"), exist_ok=True)
52
+
53
+ # Create cache directory
54
+ os.makedirs(os.path.join(base_dir, "cache"), exist_ok=True)
55
+
56
+ # Create data directory
57
+ os.makedirs(os.path.join(base_dir, "data"), exist_ok=True)
58
+
59
+
60
+ def setup_application(config_file=None):
61
+ """
62
+ Setup and configure the microservice application.
63
+
64
+ Args:
65
+ config_file: Path to configuration file (optional)
66
+
67
+ Returns:
68
+ Configured microservice object
69
+ """
70
+ # Parse command line arguments if config_file not provided
71
+ if config_file is None:
72
+ args = parse_args()
73
+ config_file = args.config
74
+
75
+ # Get absolute path to config file
76
+ current_dir = Path(__file__).parent.absolute()
77
+ config_path = current_dir / config_file
78
+
79
+ # Fall back to config.json if specified file doesn't exist
80
+ if not config_path.exists():
81
+ config_path = current_dir / "config.json"
82
+
83
+ # Create necessary directories
84
+ ensure_directories(str(config_path))
85
+
86
+ # Load configuration if exists
87
+ if config_path.exists():
88
+ config.load_from_file(str(config_path))
89
+ logger.info(f"Loaded configuration from {config_path}")
90
+ else:
91
+ logger.warning(f"Configuration file {config_path} not found, using defaults")
92
+
93
+ # Create microservice
94
+ service = MicroService(
95
+ title="Complete MCP Microservice Example",
96
+ description="Full-featured microservice with Docker support",
97
+ version="1.0.0",
98
+ config_path=str(config_path) if config_path.exists() else None
99
+ )
100
+
101
+ # Safely register commands from package
102
+ try:
103
+ # Clear any existing registrations to prevent conflicts
104
+ package_path = "commands"
105
+
106
+ # Get currently registered commands
107
+ commands = registry.get_all_commands()
108
+ for cmd_name in list(commands.keys()):
109
+ try:
110
+ registry.unregister(cmd_name)
111
+ except Exception as e:
112
+ logger.debug(f"Error unregistering command {cmd_name}: {e}")
113
+
114
+ # Discover and register commands
115
+ service.discover_commands(package_path)
116
+ logger.info(f"Discovered and registered commands from package: {package_path}")
117
+ except Exception as e:
118
+ logger.error(f"Error discovering commands: {e}")
119
+
120
+ return service
121
+
122
+
123
+ def main():
124
+ """Run microservice with command discovery."""
125
+ # Setup application
126
+ service = setup_application()
127
+
128
+ # Check if port is overridden by environment variable (for testing)
129
+ if "TEST_SERVER_PORT" in os.environ:
130
+ port = int(os.environ["TEST_SERVER_PORT"])
131
+ service.port = port
132
+ logger.info(f"Using test port from environment: {port}")
133
+
134
+ # Run server with parameters from configuration
135
+ service.run()
136
+
137
+
138
+ if __name__ == "__main__":
139
+ main()