container-manager-mcp 1.0.6__py3-none-any.whl → 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of container-manager-mcp might be problematic. Click here for more details.

@@ -8,7 +8,7 @@ from container_manager_mcp.container_manager import (
8
8
  DockerManager,
9
9
  PodmanManager,
10
10
  )
11
- from container_manager_mcp.container_manager_mcp import main
11
+ from container_manager_mcp.container_manager_mcp import container_manager_mcp
12
12
 
13
13
  """
14
14
  container-manager
@@ -17,7 +17,7 @@ Manage your containers using docker, podman, compose, or docker swarm!
17
17
  """
18
18
 
19
19
  __all__ = [
20
- "main",
20
+ "container_manager_mcp",
21
21
  "create_manager",
22
22
  "container_manager",
23
23
  "ContainerManagerBase",
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/python
2
2
  # coding: utf-8
3
- from container_manager_mcp.container_manager_mcp import main
3
+ from container_manager_mcp.container_manager_mcp import container_manager_mcp
4
4
 
5
5
  if __name__ == "__main__":
6
- main()
6
+ container_manager_mcp()
@@ -510,14 +510,17 @@ class DockerManager(ContainerManagerBase):
510
510
  self.log_action("run_container", params, result)
511
511
  return result
512
512
  attrs = container.attrs
513
- ports = attrs.get("NetworkSettings", {}).get("Ports", {})
514
513
  port_mappings = []
515
- for container_port, host_ports in ports.items():
516
- if host_ports:
517
- for hp in host_ports:
518
- port_mappings.append(
519
- f"{hp.get('HostIp', '0.0.0.0')}:{hp.get('HostPort')}->{container_port}"
520
- )
514
+ if ports: # Check if ports is not None
515
+ network_settings = attrs.get("NetworkSettings", {})
516
+ container_ports = network_settings.get("Ports", {})
517
+ if container_ports: # Check if Ports dictionary is not empty
518
+ for container_port, host_ports in container_ports.items():
519
+ if host_ports: # Check if host_ports is not None or empty
520
+ for hp in host_ports:
521
+ port_mappings.append(
522
+ f"{hp.get('HostIp', '0.0.0.0')}:{hp.get('HostPort')}->{container_port}"
523
+ )
521
524
  created = attrs.get("Created", None)
522
525
  created_str = self._parse_timestamp(created)
523
526
  result = {
@@ -1057,9 +1060,11 @@ class PodmanManager(ContainerManagerBase):
1057
1060
 
1058
1061
  def _autodetect_podman_url(self) -> Optional[str]:
1059
1062
  """Autodetect the appropriate Podman socket URL based on platform."""
1060
- base_url = os.environ.get("PODMAN_BASE_URL")
1063
+ base_url = os.environ.get("CONTAINER_MANAGER_PODMAN_BASE_URL")
1061
1064
  if base_url:
1062
- self.logger.info(f"Using PODMAN_BASE_URL from environment: {base_url}")
1065
+ self.logger.info(
1066
+ f"Using CONTAINER_MANAGER_PODMAN_BASE_URL from environment: {base_url}"
1067
+ )
1063
1068
  return base_url
1064
1069
  system = platform.system()
1065
1070
  is_wsl = self._is_wsl()
@@ -1069,6 +1074,7 @@ class PodmanManager(ContainerManagerBase):
1069
1074
  raise RuntimeError("Podman Machine is not running on Windows system")
1070
1075
  socket_candidates.extend(
1071
1076
  [
1077
+ "tcp://127.0.0.1:8080",
1072
1078
  "unix:///run/podman/podman.sock",
1073
1079
  "npipe:////./pipe/docker_engine",
1074
1080
  "unix:///mnt/wsl/podman-sockets/podman-machine-default/podman-user.sock",
@@ -1430,12 +1436,15 @@ class PodmanManager(ContainerManagerBase):
1430
1436
  self.log_action("run_container", params, result)
1431
1437
  return result
1432
1438
  attrs = container.attrs
1433
- ports = attrs.get("Ports", [])
1434
- port_mappings = [
1435
- f"{p.get('host_ip', '0.0.0.0')}:{p.get('host_port')}->{p.get('container_port')}/{p.get('protocol', 'tcp')}"
1436
- for p in ports
1437
- if p.get("host_port")
1438
- ]
1439
+ port_mappings = []
1440
+ if ports: # Check if ports is not None
1441
+ container_ports = attrs.get("Ports", [])
1442
+ if container_ports: # Check if Ports list is not empty
1443
+ port_mappings = [
1444
+ f"{p.get('host_ip', '0.0.0.0')}:{p.get('host_port')}->{p.get('container_port')}/{p.get('protocol', 'tcp')}"
1445
+ for p in container_ports
1446
+ if p.get("host_port")
1447
+ ]
1439
1448
  created = attrs.get("Created", None)
1440
1449
  created_str = self._parse_timestamp(created)
1441
1450
  result = {
@@ -62,16 +62,6 @@ def parse_image_string(image: str, default_tag: str = "latest") -> tuple[str, st
62
62
  return image, default_tag
63
63
 
64
64
 
65
- environment_silent = os.environ.get("SILENT", False)
66
- environment_log_file = os.environ.get("LOG_FILE", None)
67
- environment_container_manager_type = os.environ.get("CONTAINER_MANAGER_TYPE", None)
68
-
69
- if environment_silent:
70
- environment_silent = to_boolean(environment_silent)
71
-
72
- # Common tools
73
-
74
-
75
65
  @mcp.tool(
76
66
  annotations={
77
67
  "title": "Get Version",
@@ -85,18 +75,24 @@ if environment_silent:
85
75
  async def get_version(
86
76
  manager_type: Optional[str] = Field(
87
77
  description="Container manager: docker, podman (default: auto-detect)",
88
- default=environment_container_manager_type,
78
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
89
79
  ),
90
80
  silent: Optional[bool] = Field(
91
- description="Suppress output", default=environment_silent
81
+ description="Suppress output",
82
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
92
83
  ),
93
84
  log_file: Optional[str] = Field(
94
- description="Path to log file", default=environment_log_file
85
+ description="Path to log file",
86
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
95
87
  ),
96
88
  ctx: Context = Field(
97
89
  description="MCP context for progress reporting", default=None
98
90
  ),
99
91
  ) -> Dict:
92
+ """
93
+ Retrieves the version information of the container manager (Docker or Podman).
94
+ Returns: A dictionary with keys like 'version', 'api_version', etc., detailing the manager's version.
95
+ """
100
96
  logger = logging.getLogger("ContainerManager")
101
97
  logger.debug(
102
98
  f"Getting version for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -122,18 +118,24 @@ async def get_version(
122
118
  async def get_info(
123
119
  manager_type: Optional[str] = Field(
124
120
  description="Container manager: docker, podman (default: auto-detect)",
125
- default=environment_container_manager_type,
121
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
126
122
  ),
127
123
  silent: Optional[bool] = Field(
128
- description="Suppress output", default=environment_silent
124
+ description="Suppress output",
125
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
129
126
  ),
130
127
  log_file: Optional[str] = Field(
131
- description="Path to log file", default=environment_log_file
128
+ description="Path to log file",
129
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
132
130
  ),
133
131
  ctx: Context = Field(
134
132
  description="MCP context for progress reporting", default=None
135
133
  ),
136
134
  ) -> Dict:
135
+ """
136
+ Retrieves detailed information about the container manager system.
137
+ Returns: A dictionary containing system info such as OS, architecture, storage driver, and more.
138
+ """
137
139
  logger = logging.getLogger("ContainerManager")
138
140
  logger.debug(
139
141
  f"Getting info for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -159,18 +161,24 @@ async def get_info(
159
161
  async def list_images(
160
162
  manager_type: Optional[str] = Field(
161
163
  description="Container manager: docker, podman (default: auto-detect)",
162
- default=environment_container_manager_type,
164
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
163
165
  ),
164
166
  silent: Optional[bool] = Field(
165
- description="Suppress output", default=environment_silent
167
+ description="Suppress output",
168
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
166
169
  ),
167
170
  log_file: Optional[str] = Field(
168
- description="Path to log file", default=environment_log_file
171
+ description="Path to log file",
172
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
169
173
  ),
170
174
  ctx: Context = Field(
171
175
  description="MCP context for progress reporting", default=None
172
176
  ),
173
177
  ) -> List[Dict]:
178
+ """
179
+ Lists all container images available on the system.
180
+ Returns: A list of dictionaries, each with image details like 'id', 'tags', 'created', 'size'.
181
+ """
174
182
  logger = logging.getLogger("ContainerManager")
175
183
  logger.debug(
176
184
  f"Listing images for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -206,18 +214,24 @@ async def pull_image(
206
214
  ),
207
215
  manager_type: Optional[str] = Field(
208
216
  description="Container manager: docker, podman (default: auto-detect)",
209
- default=environment_container_manager_type,
217
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
210
218
  ),
211
219
  silent: Optional[bool] = Field(
212
- description="Suppress output", default=environment_silent
220
+ description="Suppress output",
221
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
213
222
  ),
214
223
  log_file: Optional[str] = Field(
215
- description="Path to log file", default=environment_log_file
224
+ description="Path to log file",
225
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
216
226
  ),
217
227
  ctx: Context = Field(
218
228
  description="MCP context for progress reporting", default=None
219
229
  ),
220
230
  ) -> Dict:
231
+ """
232
+ Pulls a container image from a registry.
233
+ Returns: A dictionary with the pull status, including 'id' of the pulled image and any error messages.
234
+ """
221
235
  logger = logging.getLogger("ContainerManager")
222
236
  # Parse image string to separate image and tag
223
237
  parsed_image, parsed_tag = parse_image_string(image, tag)
@@ -247,18 +261,24 @@ async def remove_image(
247
261
  force: bool = Field(description="Force removal", default=False),
248
262
  manager_type: Optional[str] = Field(
249
263
  description="Container manager: docker, podman (default: auto-detect)",
250
- default=environment_container_manager_type,
264
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
251
265
  ),
252
266
  silent: Optional[bool] = Field(
253
- description="Suppress output", default=environment_silent
267
+ description="Suppress output",
268
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
254
269
  ),
255
270
  log_file: Optional[str] = Field(
256
- description="Path to log file", default=environment_log_file
271
+ description="Path to log file",
272
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
257
273
  ),
258
274
  ctx: Context = Field(
259
275
  description="MCP context for progress reporting", default=None
260
276
  ),
261
277
  ) -> Dict:
278
+ """
279
+ Removes a specified container image.
280
+ Returns: A dictionary indicating success or failure, with details like removed image ID.
281
+ """
262
282
  logger = logging.getLogger("ContainerManager")
263
283
  logger.debug(
264
284
  f"Removing image {image} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -285,18 +305,24 @@ async def prune_images(
285
305
  all: bool = Field(description="Prune all unused images", default=False),
286
306
  manager_type: Optional[str] = Field(
287
307
  description="Container manager: docker, podman (default: auto-detect)",
288
- default=environment_container_manager_type,
308
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
289
309
  ),
290
310
  silent: Optional[bool] = Field(
291
- description="Suppress output", default=environment_silent
311
+ description="Suppress output",
312
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
292
313
  ),
293
314
  log_file: Optional[str] = Field(
294
- description="Path to log file", default=environment_log_file
315
+ description="Path to log file",
316
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
295
317
  ),
296
318
  ctx: Context = Field(
297
319
  description="MCP context for progress reporting", default=None
298
320
  ),
299
321
  ) -> Dict:
322
+ """
323
+ Prunes unused container images.
324
+ Returns: A dictionary with prune results, including space reclaimed and list of deleted images.
325
+ """
300
326
  logger = logging.getLogger("ContainerManager")
301
327
  logger.debug(
302
328
  f"Pruning images for {manager_type}, all: {all}, silent: {silent}, log_file: {log_file}"
@@ -325,18 +351,24 @@ async def list_containers(
325
351
  ),
326
352
  manager_type: Optional[str] = Field(
327
353
  description="Container manager: docker, podman (default: auto-detect)",
328
- default=environment_container_manager_type,
354
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
329
355
  ),
330
356
  silent: Optional[bool] = Field(
331
- description="Suppress output", default=environment_silent
357
+ description="Suppress output",
358
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
332
359
  ),
333
360
  log_file: Optional[str] = Field(
334
- description="Path to log file", default=environment_log_file
361
+ description="Path to log file",
362
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
335
363
  ),
336
364
  ctx: Context = Field(
337
365
  description="MCP context for progress reporting", default=None
338
366
  ),
339
367
  ) -> List[Dict]:
368
+ """
369
+ Lists containers on the system.
370
+ Returns: A list of dictionaries, each with container details like 'id', 'name', 'status', 'image'.
371
+ """
340
372
  logger = logging.getLogger("ContainerManager")
341
373
  logger.debug(
342
374
  f"Listing containers for {manager_type}, all: {all}, silent: {silent}, log_file: {log_file}"
@@ -378,18 +410,24 @@ async def run_container(
378
410
  ),
379
411
  manager_type: Optional[str] = Field(
380
412
  description="Container manager: docker, podman (default: auto-detect)",
381
- default=environment_container_manager_type,
413
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
382
414
  ),
383
415
  silent: Optional[bool] = Field(
384
- description="Suppress output", default=environment_silent
416
+ description="Suppress output",
417
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
385
418
  ),
386
419
  log_file: Optional[str] = Field(
387
- description="Path to log file", default=environment_log_file
420
+ description="Path to log file",
421
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
388
422
  ),
389
423
  ctx: Context = Field(
390
424
  description="MCP context for progress reporting", default=None
391
425
  ),
392
426
  ) -> Dict:
427
+ """
428
+ Runs a new container from the specified image.
429
+ Returns: A dictionary with the container's ID and status after starting.
430
+ """
393
431
  logger = logging.getLogger("ContainerManager")
394
432
  logger.debug(
395
433
  f"Running container from {image} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -419,18 +457,24 @@ async def stop_container(
419
457
  timeout: int = Field(description="Timeout in seconds", default=10),
420
458
  manager_type: Optional[str] = Field(
421
459
  description="Container manager: docker, podman (default: auto-detect)",
422
- default=environment_container_manager_type,
460
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
423
461
  ),
424
462
  silent: Optional[bool] = Field(
425
- description="Suppress output", default=environment_silent
463
+ description="Suppress output",
464
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
426
465
  ),
427
466
  log_file: Optional[str] = Field(
428
- description="Path to log file", default=environment_log_file
467
+ description="Path to log file",
468
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
429
469
  ),
430
470
  ctx: Context = Field(
431
471
  description="MCP context for progress reporting", default=None
432
472
  ),
433
473
  ) -> Dict:
474
+ """
475
+ Stops a running container.
476
+ Returns: A dictionary confirming the stop action, with container ID and any errors.
477
+ """
434
478
  logger = logging.getLogger("ContainerManager")
435
479
  logger.debug(
436
480
  f"Stopping container {container_id} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -458,18 +502,24 @@ async def remove_container(
458
502
  force: bool = Field(description="Force removal", default=False),
459
503
  manager_type: Optional[str] = Field(
460
504
  description="Container manager: docker, podman (default: auto-detect)",
461
- default=environment_container_manager_type,
505
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
462
506
  ),
463
507
  silent: Optional[bool] = Field(
464
- description="Suppress output", default=environment_silent
508
+ description="Suppress output",
509
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
465
510
  ),
466
511
  log_file: Optional[str] = Field(
467
- description="Path to log file", default=environment_log_file
512
+ description="Path to log file",
513
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
468
514
  ),
469
515
  ctx: Context = Field(
470
516
  description="MCP context for progress reporting", default=None
471
517
  ),
472
518
  ) -> Dict:
519
+ """
520
+ Removes a container.
521
+ Returns: A dictionary with removal status, including deleted container ID.
522
+ """
473
523
  logger = logging.getLogger("ContainerManager")
474
524
  logger.debug(
475
525
  f"Removing container {container_id} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -495,18 +545,24 @@ async def remove_container(
495
545
  async def prune_containers(
496
546
  manager_type: Optional[str] = Field(
497
547
  description="Container manager: docker, podman (default: auto-detect)",
498
- default=environment_container_manager_type,
548
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
499
549
  ),
500
550
  silent: Optional[bool] = Field(
501
- description="Suppress output", default=environment_silent
551
+ description="Suppress output",
552
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
502
553
  ),
503
554
  log_file: Optional[str] = Field(
504
- description="Path to log file", default=environment_log_file
555
+ description="Path to log file",
556
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
505
557
  ),
506
558
  ctx: Context = Field(
507
559
  description="MCP context for progress reporting", default=None
508
560
  ),
509
561
  ) -> Dict:
562
+ """
563
+ Prunes stopped containers.
564
+ Returns: A dictionary with prune results, including space reclaimed and deleted containers.
565
+ """
510
566
  logger = logging.getLogger("ContainerManager")
511
567
  logger.debug(
512
568
  f"Pruning containers for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -536,18 +592,24 @@ async def get_container_logs(
536
592
  ),
537
593
  manager_type: Optional[str] = Field(
538
594
  description="Container manager: docker, podman (default: auto-detect)",
539
- default=environment_container_manager_type,
595
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
540
596
  ),
541
597
  silent: Optional[bool] = Field(
542
- description="Suppress output", default=environment_silent
598
+ description="Suppress output",
599
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
543
600
  ),
544
601
  log_file: Optional[str] = Field(
545
- description="Path to log file", default=environment_log_file
602
+ description="Path to log file",
603
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
546
604
  ),
547
605
  ctx: Context = Field(
548
606
  description="MCP context for progress reporting", default=None
549
607
  ),
550
608
  ) -> str:
609
+ """
610
+ Retrieves logs from a container.
611
+ Returns: A string containing the log output, parse as plain text lines.
612
+ """
551
613
  logger = logging.getLogger("ContainerManager")
552
614
  logger.debug(
553
615
  f"Getting logs for container {container_id} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -576,18 +638,24 @@ async def exec_in_container(
576
638
  detach: bool = Field(description="Detach execution", default=False),
577
639
  manager_type: Optional[str] = Field(
578
640
  description="Container manager: docker, podman (default: auto-detect)",
579
- default=environment_container_manager_type,
641
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
580
642
  ),
581
643
  silent: Optional[bool] = Field(
582
- description="Suppress output", default=environment_silent
644
+ description="Suppress output",
645
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
583
646
  ),
584
647
  log_file: Optional[str] = Field(
585
- description="Path to log file", default=environment_log_file
648
+ description="Path to log file",
649
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
586
650
  ),
587
651
  ctx: Context = Field(
588
652
  description="MCP context for progress reporting", default=None
589
653
  ),
590
654
  ) -> Dict:
655
+ """
656
+ Executes a command inside a running container.
657
+ Returns: A dictionary with execution results, including 'exit_code' and 'output' as string.
658
+ """
591
659
  logger = logging.getLogger("ContainerManager")
592
660
  logger.debug(
593
661
  f"Executing {command} in container {container_id} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -613,18 +681,24 @@ async def exec_in_container(
613
681
  async def list_volumes(
614
682
  manager_type: Optional[str] = Field(
615
683
  description="Container manager: docker, podman (default: auto-detect)",
616
- default=environment_container_manager_type,
684
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
617
685
  ),
618
686
  silent: Optional[bool] = Field(
619
- description="Suppress output", default=environment_silent
687
+ description="Suppress output",
688
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
620
689
  ),
621
690
  log_file: Optional[str] = Field(
622
- description="Path to log file", default=environment_log_file
691
+ description="Path to log file",
692
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
623
693
  ),
624
694
  ctx: Context = Field(
625
695
  description="MCP context for progress reporting", default=None
626
696
  ),
627
697
  ) -> Dict:
698
+ """
699
+ Lists all volumes.
700
+ Returns: A dictionary with 'volumes' as a list of dicts containing name, driver, mountpoint, etc.
701
+ """
628
702
  logger = logging.getLogger("ContainerManager")
629
703
  logger.debug(
630
704
  f"Listing volumes for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -651,18 +725,24 @@ async def create_volume(
651
725
  name: str = Field(description="Volume name"),
652
726
  manager_type: Optional[str] = Field(
653
727
  description="Container manager: docker, podman (default: auto-detect)",
654
- default=environment_container_manager_type,
728
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
655
729
  ),
656
730
  silent: Optional[bool] = Field(
657
- description="Suppress output", default=environment_silent
731
+ description="Suppress output",
732
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
658
733
  ),
659
734
  log_file: Optional[str] = Field(
660
- description="Path to log file", default=environment_log_file
735
+ description="Path to log file",
736
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
661
737
  ),
662
738
  ctx: Context = Field(
663
739
  description="MCP context for progress reporting", default=None
664
740
  ),
665
741
  ) -> Dict:
742
+ """
743
+ Creates a new volume.
744
+ Returns: A dictionary with details of the created volume, like 'name' and 'mountpoint'.
745
+ """
666
746
  logger = logging.getLogger("ContainerManager")
667
747
  logger.debug(
668
748
  f"Creating volume {name} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -690,18 +770,24 @@ async def remove_volume(
690
770
  force: bool = Field(description="Force removal", default=False),
691
771
  manager_type: Optional[str] = Field(
692
772
  description="Container manager: docker, podman (default: auto-detect)",
693
- default=environment_container_manager_type,
773
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
694
774
  ),
695
775
  silent: Optional[bool] = Field(
696
- description="Suppress output", default=environment_silent
776
+ description="Suppress output",
777
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
697
778
  ),
698
779
  log_file: Optional[str] = Field(
699
- description="Path to log file", default=environment_log_file
780
+ description="Path to log file",
781
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
700
782
  ),
701
783
  ctx: Context = Field(
702
784
  description="MCP context for progress reporting", default=None
703
785
  ),
704
786
  ) -> Dict:
787
+ """
788
+ Removes a volume.
789
+ Returns: A dictionary confirming removal, with deleted volume name.
790
+ """
705
791
  logger = logging.getLogger("ContainerManager")
706
792
  logger.debug(
707
793
  f"Removing volume {name} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -728,18 +814,24 @@ async def prune_volumes(
728
814
  all: bool = Field(description="Remove all volumes (dangerous)", default=False),
729
815
  manager_type: Optional[str] = Field(
730
816
  description="Container manager: docker, podman (default: auto-detect)",
731
- default=environment_container_manager_type,
817
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
732
818
  ),
733
819
  silent: Optional[bool] = Field(
734
- description="Suppress output", default=environment_silent
820
+ description="Suppress output",
821
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
735
822
  ),
736
823
  log_file: Optional[str] = Field(
737
- description="Path to log file", default=environment_log_file
824
+ description="Path to log file",
825
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
738
826
  ),
739
827
  ctx: Context = Field(
740
828
  description="MCP context for progress reporting", default=None
741
829
  ),
742
830
  ) -> Dict:
831
+ """
832
+ Prunes unused volumes.
833
+ Returns: A dictionary with prune results, including space reclaimed and deleted volumes.
834
+ """
743
835
  logger = logging.getLogger("ContainerManager")
744
836
  logger.debug(
745
837
  f"Pruning volumes for {manager_type}, all: {all}, silent: {silent}, log_file: {log_file}"
@@ -765,18 +857,24 @@ async def prune_volumes(
765
857
  async def list_networks(
766
858
  manager_type: Optional[str] = Field(
767
859
  description="Container manager: docker, podman (default: auto-detect)",
768
- default=environment_container_manager_type,
860
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
769
861
  ),
770
862
  silent: Optional[bool] = Field(
771
- description="Suppress output", default=environment_silent
863
+ description="Suppress output",
864
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
772
865
  ),
773
866
  log_file: Optional[str] = Field(
774
- description="Path to log file", default=environment_log_file
867
+ description="Path to log file",
868
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
775
869
  ),
776
870
  ctx: Context = Field(
777
871
  description="MCP context for progress reporting", default=None
778
872
  ),
779
873
  ) -> List[Dict]:
874
+ """
875
+ Lists all networks.
876
+ Returns: A list of dictionaries, each with network details like 'id', 'name', 'driver', 'scope'.
877
+ """
780
878
  logger = logging.getLogger("ContainerManager")
781
879
  logger.debug(
782
880
  f"Listing networks for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -804,18 +902,24 @@ async def create_network(
804
902
  driver: str = Field(description="Network driver (e.g., bridge)", default="bridge"),
805
903
  manager_type: Optional[str] = Field(
806
904
  description="Container manager: docker, podman (default: auto-detect)",
807
- default=environment_container_manager_type,
905
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
808
906
  ),
809
907
  silent: Optional[bool] = Field(
810
- description="Suppress output", default=environment_silent
908
+ description="Suppress output",
909
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
811
910
  ),
812
911
  log_file: Optional[str] = Field(
813
- description="Path to log file", default=environment_log_file
912
+ description="Path to log file",
913
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
814
914
  ),
815
915
  ctx: Context = Field(
816
916
  description="MCP context for progress reporting", default=None
817
917
  ),
818
918
  ) -> Dict:
919
+ """
920
+ Creates a new network.
921
+ Returns: A dictionary with the created network's ID and details.
922
+ """
819
923
  logger = logging.getLogger("ContainerManager")
820
924
  logger.debug(
821
925
  f"Creating network {name} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -842,18 +946,24 @@ async def remove_network(
842
946
  network_id: str = Field(description="Network ID or name"),
843
947
  manager_type: Optional[str] = Field(
844
948
  description="Container manager: docker, podman (default: auto-detect)",
845
- default=environment_container_manager_type,
949
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
846
950
  ),
847
951
  silent: Optional[bool] = Field(
848
- description="Suppress output", default=environment_silent
952
+ description="Suppress output",
953
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
849
954
  ),
850
955
  log_file: Optional[str] = Field(
851
- description="Path to log file", default=environment_log_file
956
+ description="Path to log file",
957
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
852
958
  ),
853
959
  ctx: Context = Field(
854
960
  description="MCP context for progress reporting", default=None
855
961
  ),
856
962
  ) -> Dict:
963
+ """
964
+ Removes a network.
965
+ Returns: A dictionary confirming removal, with deleted network ID.
966
+ """
857
967
  logger = logging.getLogger("ContainerManager")
858
968
  logger.debug(
859
969
  f"Removing network {network_id} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -879,18 +989,24 @@ async def remove_network(
879
989
  async def prune_networks(
880
990
  manager_type: Optional[str] = Field(
881
991
  description="Container manager: docker, podman (default: auto-detect)",
882
- default=environment_container_manager_type,
992
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
883
993
  ),
884
994
  silent: Optional[bool] = Field(
885
- description="Suppress output", default=environment_silent
995
+ description="Suppress output",
996
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
886
997
  ),
887
998
  log_file: Optional[str] = Field(
888
- description="Path to log file", default=environment_log_file
999
+ description="Path to log file",
1000
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
889
1001
  ),
890
1002
  ctx: Context = Field(
891
1003
  description="MCP context for progress reporting", default=None
892
1004
  ),
893
1005
  ) -> Dict:
1006
+ """
1007
+ Prunes unused networks.
1008
+ Returns: A dictionary with prune results, including deleted networks.
1009
+ """
894
1010
  logger = logging.getLogger("ContainerManager")
895
1011
  logger.debug(
896
1012
  f"Pruning networks for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -918,18 +1034,24 @@ async def prune_system(
918
1034
  all: bool = Field(description="Prune all unused resources", default=False),
919
1035
  manager_type: Optional[str] = Field(
920
1036
  description="Container manager: docker, podman (default: auto-detect)",
921
- default=environment_container_manager_type,
1037
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
922
1038
  ),
923
1039
  silent: Optional[bool] = Field(
924
- description="Suppress output", default=environment_silent
1040
+ description="Suppress output",
1041
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
925
1042
  ),
926
1043
  log_file: Optional[str] = Field(
927
- description="Path to log file", default=environment_log_file
1044
+ description="Path to log file",
1045
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
928
1046
  ),
929
1047
  ctx: Context = Field(
930
1048
  description="MCP context for progress reporting", default=None
931
1049
  ),
932
1050
  ) -> Dict:
1051
+ """
1052
+ Prunes all unused system resources (containers, images, volumes, networks).
1053
+ Returns: A dictionary summarizing the prune operation across resources.
1054
+ """
933
1055
  logger = logging.getLogger("ContainerManager")
934
1056
  logger.debug(
935
1057
  f"Pruning system for {manager_type}, force: {force}, all: {all}, silent: {silent}, log_file: {log_file}"
@@ -961,18 +1083,24 @@ async def init_swarm(
961
1083
  ),
962
1084
  manager_type: Optional[str] = Field(
963
1085
  description="Container manager: must be docker for swarm (default: auto-detect)",
964
- default=environment_container_manager_type,
1086
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
965
1087
  ),
966
1088
  silent: Optional[bool] = Field(
967
- description="Suppress output", default=environment_silent
1089
+ description="Suppress output",
1090
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
968
1091
  ),
969
1092
  log_file: Optional[str] = Field(
970
- description="Path to log file", default=environment_log_file
1093
+ description="Path to log file",
1094
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
971
1095
  ),
972
1096
  ctx: Context = Field(
973
1097
  description="MCP context for progress reporting", default=None
974
1098
  ),
975
1099
  ) -> Dict:
1100
+ """
1101
+ Initializes a Docker Swarm cluster.
1102
+ Returns: A dictionary with swarm info, including join tokens for manager and worker.
1103
+ """
976
1104
  if manager_type and manager_type != "docker":
977
1105
  raise ValueError("Swarm operations are only supported on Docker")
978
1106
  logger = logging.getLogger("ContainerManager")
@@ -1001,18 +1129,24 @@ async def leave_swarm(
1001
1129
  force: bool = Field(description="Force leave", default=False),
1002
1130
  manager_type: Optional[str] = Field(
1003
1131
  description="Container manager: must be docker for swarm (default: auto-detect)",
1004
- default=environment_container_manager_type,
1132
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1005
1133
  ),
1006
1134
  silent: Optional[bool] = Field(
1007
- description="Suppress output", default=environment_silent
1135
+ description="Suppress output",
1136
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1008
1137
  ),
1009
1138
  log_file: Optional[str] = Field(
1010
- description="Path to log file", default=environment_log_file
1139
+ description="Path to log file",
1140
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1011
1141
  ),
1012
1142
  ctx: Context = Field(
1013
1143
  description="MCP context for progress reporting", default=None
1014
1144
  ),
1015
1145
  ) -> Dict:
1146
+ """
1147
+ Leaves the Docker Swarm cluster.
1148
+ Returns: A dictionary confirming the leave action.
1149
+ """
1016
1150
  if manager_type and manager_type != "docker":
1017
1151
  raise ValueError("Swarm operations are only supported on Docker")
1018
1152
  logger = logging.getLogger("ContainerManager")
@@ -1040,18 +1174,24 @@ async def leave_swarm(
1040
1174
  async def list_nodes(
1041
1175
  manager_type: Optional[str] = Field(
1042
1176
  description="Container manager: must be docker for swarm (default: auto-detect)",
1043
- default=environment_container_manager_type,
1177
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1044
1178
  ),
1045
1179
  silent: Optional[bool] = Field(
1046
- description="Suppress output", default=environment_silent
1180
+ description="Suppress output",
1181
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1047
1182
  ),
1048
1183
  log_file: Optional[str] = Field(
1049
- description="Path to log file", default=environment_log_file
1184
+ description="Path to log file",
1185
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1050
1186
  ),
1051
1187
  ctx: Context = Field(
1052
1188
  description="MCP context for progress reporting", default=None
1053
1189
  ),
1054
1190
  ) -> List[Dict]:
1191
+ """
1192
+ Lists nodes in the Docker Swarm cluster.
1193
+ Returns: A list of dictionaries, each with node details like 'id', 'hostname', 'status', 'role'.
1194
+ """
1055
1195
  if manager_type and manager_type != "docker":
1056
1196
  raise ValueError("Swarm operations are only supported on Docker")
1057
1197
  logger = logging.getLogger("ContainerManager")
@@ -1079,18 +1219,24 @@ async def list_nodes(
1079
1219
  async def list_services(
1080
1220
  manager_type: Optional[str] = Field(
1081
1221
  description="Container manager: must be docker for swarm (default: auto-detect)",
1082
- default=environment_container_manager_type,
1222
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1083
1223
  ),
1084
1224
  silent: Optional[bool] = Field(
1085
- description="Suppress output", default=environment_silent
1225
+ description="Suppress output",
1226
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1086
1227
  ),
1087
1228
  log_file: Optional[str] = Field(
1088
- description="Path to log file", default=environment_log_file
1229
+ description="Path to log file",
1230
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1089
1231
  ),
1090
1232
  ctx: Context = Field(
1091
1233
  description="MCP context for progress reporting", default=None
1092
1234
  ),
1093
1235
  ) -> List[Dict]:
1236
+ """
1237
+ Lists services in the Docker Swarm.
1238
+ Returns: A list of dictionaries, each with service details like 'id', 'name', 'replicas', 'image'.
1239
+ """
1094
1240
  if manager_type and manager_type != "docker":
1095
1241
  raise ValueError("Swarm operations are only supported on Docker")
1096
1242
  logger = logging.getLogger("ContainerManager")
@@ -1127,18 +1273,24 @@ async def create_service(
1127
1273
  ),
1128
1274
  manager_type: Optional[str] = Field(
1129
1275
  description="Container manager: must be docker for swarm (default: auto-detect)",
1130
- default=environment_container_manager_type,
1276
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1131
1277
  ),
1132
1278
  silent: Optional[bool] = Field(
1133
- description="Suppress output", default=environment_silent
1279
+ description="Suppress output",
1280
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1134
1281
  ),
1135
1282
  log_file: Optional[str] = Field(
1136
- description="Path to log file", default=environment_log_file
1283
+ description="Path to log file",
1284
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1137
1285
  ),
1138
1286
  ctx: Context = Field(
1139
1287
  description="MCP context for progress reporting", default=None
1140
1288
  ),
1141
1289
  ) -> Dict:
1290
+ """
1291
+ Creates a new service in Docker Swarm.
1292
+ Returns: A dictionary with the created service's ID and details.
1293
+ """
1142
1294
  if manager_type and manager_type != "docker":
1143
1295
  raise ValueError("Swarm operations are only supported on Docker")
1144
1296
  logger = logging.getLogger("ContainerManager")
@@ -1167,18 +1319,24 @@ async def remove_service(
1167
1319
  service_id: str = Field(description="Service ID or name"),
1168
1320
  manager_type: Optional[str] = Field(
1169
1321
  description="Container manager: must be docker for swarm (default: auto-detect)",
1170
- default=environment_container_manager_type,
1322
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1171
1323
  ),
1172
1324
  silent: Optional[bool] = Field(
1173
- description="Suppress output", default=environment_silent
1325
+ description="Suppress output",
1326
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1174
1327
  ),
1175
1328
  log_file: Optional[str] = Field(
1176
- description="Path to log file", default=environment_log_file
1329
+ description="Path to log file",
1330
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1177
1331
  ),
1178
1332
  ctx: Context = Field(
1179
1333
  description="MCP context for progress reporting", default=None
1180
1334
  ),
1181
1335
  ) -> Dict:
1336
+ """
1337
+ Removes a service from Docker Swarm.
1338
+ Returns: A dictionary confirming the removal.
1339
+ """
1182
1340
  if manager_type and manager_type != "docker":
1183
1341
  raise ValueError("Swarm operations are only supported on Docker")
1184
1342
  logger = logging.getLogger("ContainerManager")
@@ -1209,18 +1367,24 @@ async def compose_up(
1209
1367
  build: bool = Field(description="Build images", default=False),
1210
1368
  manager_type: Optional[str] = Field(
1211
1369
  description="Container manager: docker, podman (default: auto-detect)",
1212
- default=environment_container_manager_type,
1370
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1213
1371
  ),
1214
1372
  silent: Optional[bool] = Field(
1215
- description="Suppress output", default=environment_silent
1373
+ description="Suppress output",
1374
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1216
1375
  ),
1217
1376
  log_file: Optional[str] = Field(
1218
- description="Path to log file", default=environment_log_file
1377
+ description="Path to log file",
1378
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1219
1379
  ),
1220
1380
  ctx: Context = Field(
1221
1381
  description="MCP context for progress reporting", default=None
1222
1382
  ),
1223
1383
  ) -> str:
1384
+ """
1385
+ Starts services defined in a Docker Compose file.
1386
+ Returns: A string with the output of the compose up command, parse for status messages.
1387
+ """
1224
1388
  logger = logging.getLogger("ContainerManager")
1225
1389
  logger.debug(
1226
1390
  f"Compose up {compose_file} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -1247,18 +1411,24 @@ async def compose_down(
1247
1411
  compose_file: str = Field(description="Path to compose file"),
1248
1412
  manager_type: Optional[str] = Field(
1249
1413
  description="Container manager: docker, podman (default: auto-detect)",
1250
- default=environment_container_manager_type,
1414
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1251
1415
  ),
1252
1416
  silent: Optional[bool] = Field(
1253
- description="Suppress output", default=environment_silent
1417
+ description="Suppress output",
1418
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1254
1419
  ),
1255
1420
  log_file: Optional[str] = Field(
1256
- description="Path to log file", default=environment_log_file
1421
+ description="Path to log file",
1422
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1257
1423
  ),
1258
1424
  ctx: Context = Field(
1259
1425
  description="MCP context for progress reporting", default=None
1260
1426
  ),
1261
1427
  ) -> str:
1428
+ """
1429
+ Stops and removes services from a Docker Compose file.
1430
+ Returns: A string with the output of the compose down command, parse for status messages.
1431
+ """
1262
1432
  logger = logging.getLogger("ContainerManager")
1263
1433
  logger.debug(
1264
1434
  f"Compose down {compose_file} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -1285,18 +1455,24 @@ async def compose_ps(
1285
1455
  compose_file: str = Field(description="Path to compose file"),
1286
1456
  manager_type: Optional[str] = Field(
1287
1457
  description="Container manager: docker, podman (default: auto-detect)",
1288
- default=environment_container_manager_type,
1458
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1289
1459
  ),
1290
1460
  silent: Optional[bool] = Field(
1291
- description="Suppress output", default=environment_silent
1461
+ description="Suppress output",
1462
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1292
1463
  ),
1293
1464
  log_file: Optional[str] = Field(
1294
- description="Path to log file", default=environment_log_file
1465
+ description="Path to log file",
1466
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1295
1467
  ),
1296
1468
  ctx: Context = Field(
1297
1469
  description="MCP context for progress reporting", default=None
1298
1470
  ),
1299
1471
  ) -> str:
1472
+ """
1473
+ Lists containers for a Docker Compose project.
1474
+ Returns: A string in table format listing name, command, state, ports; parse as text table.
1475
+ """
1300
1476
  logger = logging.getLogger("ContainerManager")
1301
1477
  logger.debug(
1302
1478
  f"Compose ps {compose_file} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -1324,18 +1500,24 @@ async def compose_logs(
1324
1500
  service: Optional[str] = Field(description="Specific service", default=None),
1325
1501
  manager_type: Optional[str] = Field(
1326
1502
  description="Container manager: docker, podman (default: auto-detect)",
1327
- default=environment_container_manager_type,
1503
+ default=os.environ.get("CONTAINER_MANAGER_TYPE", None),
1328
1504
  ),
1329
1505
  silent: Optional[bool] = Field(
1330
- description="Suppress output", default=environment_silent
1506
+ description="Suppress output",
1507
+ default=to_boolean(os.environ.get("CONTAINER_MANAGER_SILENT", False)),
1331
1508
  ),
1332
1509
  log_file: Optional[str] = Field(
1333
- description="Path to log file", default=environment_log_file
1510
+ description="Path to log file",
1511
+ default=os.environ.get("CONTAINER_MANAGER_LOG_FILE", None),
1334
1512
  ),
1335
1513
  ctx: Context = Field(
1336
1514
  description="MCP context for progress reporting", default=None
1337
1515
  ),
1338
1516
  ) -> str:
1517
+ """
1518
+ Retrieves logs for services in a Docker Compose project.
1519
+ Returns: A string containing combined log output, prefixed by service names; parse as text lines.
1520
+ """
1339
1521
  logger = logging.getLogger("ContainerManager")
1340
1522
  logger.debug(
1341
1523
  f"Compose logs {compose_file} for {manager_type}, silent: {silent}, log_file: {log_file}"
@@ -1375,9 +1557,5 @@ def container_manager_mcp():
1375
1557
  sys.exit(1)
1376
1558
 
1377
1559
 
1378
- def main():
1379
- container_manager_mcp()
1380
-
1381
-
1382
1560
  if __name__ == "__main__":
1383
1561
  container_manager_mcp()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: container-manager-mcp
3
- Version: 1.0.6
3
+ Version: 1.1.0
4
4
  Summary: Container Manager manage Docker, Docker Swarm, and Podman containers as an MCP Server
5
5
  Author-email: Audel Rouhi <knucklessg1@gmail.com>
6
6
  License: MIT
@@ -48,7 +48,7 @@ Dynamic: license-file
48
48
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/container-manager-mcp)
49
49
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/container-manager-mcp)
50
50
 
51
- *Version: 1.0.6*
51
+ *Version: 1.1.0*
52
52
 
53
53
  Container Manager MCP Server provides a robust interface to manage Docker and Podman containers, networks, volumes, and Docker Swarm services through a FastMCP server, enabling programmatic and remote container management.
54
54
 
@@ -123,8 +123,10 @@ Configure `mcp.json`
123
123
  "container-manager-mcp"
124
124
  ],
125
125
  "env": {
126
- "SILENT": "False", //Optional
127
- "LOG_FILE": "~/Documents/container_manager_mcp.log" //Optional
126
+ "CONTAINER_MANAGER_SILENT": "False", //Optional
127
+ "CONTAINER_MANAGER_LOG_FILE": "~/Documents/container_manager_mcp.log" //Optional
128
+ "CONTAINER_MANAGER_TYPE": "podman", //Optional
129
+ "CONTAINER_MANAGER_PODMAN_BASE_URL": "tcp://127.0.0.1:8080" //Optional
128
130
  },
129
131
  "timeout": 200000
130
132
  }
@@ -0,0 +1,10 @@
1
+ container_manager_mcp/__init__.py,sha256=2jGc7NMMlaj8-VhO0Z3KpQM50bB_fweiex-hDBfVTWo,540
2
+ container_manager_mcp/__main__.py,sha256=4bpregRyaWJBXOg9_h_F4xcHcX6bPVLL48V2EuwNGBs,168
3
+ container_manager_mcp/container_manager.py,sha256=Rtqrb4H05thq_i7z7v7M33m5rrNZ1V5rYWwV2NC8Zwo,89504
4
+ container_manager_mcp/container_manager_mcp.py,sha256=qeyOZAv7rgOVwjHZuIxb6gBeHvoz8gG9p7dSRDXTvYA,55003
5
+ container_manager_mcp-1.1.0.dist-info/licenses/LICENSE,sha256=Z1xmcrPHBnGCETO_LLQJUeaSNBSnuptcDVTt4kaPUOE,1060
6
+ container_manager_mcp-1.1.0.dist-info/METADATA,sha256=Wgr36FGeQrKP9tWSDnpHMbGgJDsbestwVH506_2SNsY,8452
7
+ container_manager_mcp-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ container_manager_mcp-1.1.0.dist-info/entry_points.txt,sha256=n7fE9uXdRktmjvZwyaiQkY0Dd7tMN6AKiHav0ZQdE2I,186
9
+ container_manager_mcp-1.1.0.dist-info/top_level.txt,sha256=B7QQLOd9mBdu0lsPKqyu4T8-zUtbqKzQJbMbtAzoozU,22
10
+ container_manager_mcp-1.1.0.dist-info/RECORD,,
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ container-manager = container_manager_mcp.container_manager:container_manager
3
+ container-manager-mcp = container_manager_mcp.container_manager_mcp:container_manager_mcp
@@ -1,10 +0,0 @@
1
- container_manager_mcp/__init__.py,sha256=N3bhKd_oh5YmBBl9N1omfZgaXhJyP0vOzH4VKxs68_g,506
2
- container_manager_mcp/__main__.py,sha256=zic5tX336HG8LfdzQQ0sDVx-tMSOsgOZCtaxHWgJ4Go,134
3
- container_manager_mcp/container_manager.py,sha256=O-Dk6q-QSQJbzHVHC3KeljJuGoDdkjlTcaCwC_4hdgo,88877
4
- container_manager_mcp/container_manager_mcp.py,sha256=E3FOTFILyYYoJF3Erkpl5zapkiDi2pKlJlkZByc-8QE,47361
5
- container_manager_mcp-1.0.6.dist-info/licenses/LICENSE,sha256=Z1xmcrPHBnGCETO_LLQJUeaSNBSnuptcDVTt4kaPUOE,1060
6
- container_manager_mcp-1.0.6.dist-info/METADATA,sha256=WygJ6UaeqBGVthdIZvSYbl40n2M40F2aL-toAm2zq8o,8238
7
- container_manager_mcp-1.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- container_manager_mcp-1.0.6.dist-info/entry_points.txt,sha256=I23pXcCgAShlfYbENzs3kbw3l1lU9Gy7lODPfRqeeiA,156
9
- container_manager_mcp-1.0.6.dist-info/top_level.txt,sha256=B7QQLOd9mBdu0lsPKqyu4T8-zUtbqKzQJbMbtAzoozU,22
10
- container_manager_mcp-1.0.6.dist-info/RECORD,,
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- container-manager = container_manager_mcp.container_manager:main
3
- container-manager-mcp = container_manager_mcp.container_manager_mcp:main