container-manager-mcp 0.0.11__py3-none-any.whl → 0.0.12__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.
@@ -9,7 +9,8 @@ from typing import List, Dict, Optional, Any
9
9
  import getopt
10
10
  import json
11
11
  import subprocess
12
- from datetime import datetime # Added for consistent timestamp formatting
12
+ from datetime import datetime
13
+ import dateutil.parser
13
14
 
14
15
  try:
15
16
  import docker
@@ -27,6 +28,7 @@ except ImportError:
27
28
 
28
29
 
29
30
  class ContainerManagerBase(ABC):
31
+
30
32
  def __init__(self, silent: bool = False, log_file: str = None):
31
33
  self.silent = silent
32
34
  self.setup_logging(log_file)
@@ -66,6 +68,20 @@ class ContainerManagerBase(ABC):
66
68
  size_bytes /= 1024.0
67
69
  return f"{size_bytes:.2f}PB"
68
70
 
71
+ def _parse_timestamp(self, timestamp: Any) -> str:
72
+ """Parse timestamp (integer or string) to ISO 8601 string."""
73
+ if not timestamp:
74
+ return "unknown"
75
+ if isinstance(timestamp, (int, float)):
76
+ return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%dT%H:%M:%S")
77
+ if isinstance(timestamp, str):
78
+ try:
79
+ parsed = dateutil.parser.isoparse(timestamp)
80
+ return parsed.strftime("%Y-%m-%dT%H:%M:%S")
81
+ except ValueError:
82
+ return "unknown"
83
+ return "unknown"
84
+
69
85
  @abstractmethod
70
86
  def get_version(self) -> Dict:
71
87
  pass
@@ -208,42 +224,6 @@ class DockerManager(ContainerManagerBase):
208
224
  self.logger.error(f"Failed to connect to Docker daemon: {str(e)}")
209
225
  raise RuntimeError(f"Failed to connect to Docker: {str(e)}")
210
226
 
211
- def get_version(self) -> Dict:
212
- params = {}
213
- try:
214
- version = self.client.version()
215
- result = {
216
- "version": version.get("Version", "unknown"),
217
- "api_version": version.get("ApiVersion", "unknown"),
218
- "os": version.get("Os", "unknown"),
219
- "arch": version.get("Arch", "unknown"),
220
- "build_time": version.get("BuildTime", "unknown"),
221
- }
222
- self.log_action("get_version", params, result)
223
- return result
224
- except Exception as e:
225
- self.log_action("get_version", params, error=e)
226
- raise RuntimeError(f"Failed to get version: {str(e)}")
227
-
228
- def get_info(self) -> Dict:
229
- params = {}
230
- try:
231
- info = self.client.info()
232
- result = {
233
- "containers_total": info.get("Containers", 0),
234
- "containers_running": info.get("ContainersRunning", 0),
235
- "images": info.get("Images", 0),
236
- "driver": info.get("Driver", "unknown"),
237
- "platform": f"{info.get('OperatingSystem', 'unknown')} {info.get('Architecture', 'unknown')}",
238
- "memory_total": self._format_size(info.get("MemTotal", 0)),
239
- "swap_total": self._format_size(info.get("SwapTotal", 0)),
240
- }
241
- self.log_action("get_info", params, result)
242
- return result
243
- except Exception as e:
244
- self.log_action("get_info", params, error=e)
245
- raise RuntimeError(f"Failed to get info: {str(e)}")
246
-
247
227
  def list_images(self) -> List[Dict]:
248
228
  params = {}
249
229
  try:
@@ -257,12 +237,8 @@ class DockerManager(ContainerManagerBase):
257
237
  repo_tag.rsplit(":", 1) if ":" in repo_tag else ("<none>", "<none>")
258
238
  )
259
239
 
260
- created = attrs.get("Created", 0)
261
- created_str = (
262
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
263
- if created
264
- else "unknown"
265
- )
240
+ created = attrs.get("Created", None)
241
+ created_str = self._parse_timestamp(created)
266
242
 
267
243
  size_bytes = attrs.get("Size", 0)
268
244
  size_str = self._format_size(size_bytes) if size_bytes else "0B"
@@ -298,12 +274,8 @@ class DockerManager(ContainerManagerBase):
298
274
  repository, tag = (
299
275
  repo_tag.rsplit(":", 1) if ":" in repo_tag else (image, tag)
300
276
  )
301
- created = attrs.get("Created", 0)
302
- created_str = (
303
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
304
- if created
305
- else "unknown"
306
- )
277
+ created = attrs.get("Created", None)
278
+ created_str = self._parse_timestamp(created)
307
279
  size_bytes = attrs.get("Size", 0)
308
280
  size_str = self._format_size(size_bytes) if size_bytes else "0B"
309
281
  result = {
@@ -321,17 +293,6 @@ class DockerManager(ContainerManagerBase):
321
293
  self.log_action("pull_image", params, error=e)
322
294
  raise RuntimeError(f"Failed to pull image: {str(e)}")
323
295
 
324
- def remove_image(self, image: str, force: bool = False) -> Dict:
325
- params = {"image": image, "force": force}
326
- try:
327
- self.client.images.remove(image, force=force)
328
- result = {"removed": image}
329
- self.log_action("remove_image", params, result)
330
- return result
331
- except Exception as e:
332
- self.log_action("remove_image", params, error=e)
333
- raise RuntimeError(f"Failed to remove image: {str(e)}")
334
-
335
296
  def list_containers(self, all: bool = False) -> List[Dict]:
336
297
  params = {"all": all}
337
298
  try:
@@ -347,12 +308,8 @@ class DockerManager(ContainerManagerBase):
347
308
  port_mappings.append(
348
309
  f"{hp.get('HostIp', '0.0.0.0')}:{hp.get('HostPort')}->{container_port}"
349
310
  )
350
- created = attrs.get("Created", 0)
351
- created_str = (
352
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
353
- if created
354
- else "unknown"
355
- )
311
+ created = attrs.get("Created", None)
312
+ created_str = self._parse_timestamp(created)
356
313
  simplified = {
357
314
  "id": attrs.get("Id", "unknown")[7:19],
358
315
  "image": attrs.get("Config", {}).get("Image", "unknown"),
@@ -410,12 +367,8 @@ class DockerManager(ContainerManagerBase):
410
367
  port_mappings.append(
411
368
  f"{hp.get('HostIp', '0.0.0.0')}:{hp.get('HostPort')}->{container_port}"
412
369
  )
413
- created = attrs.get("Created", 0)
414
- created_str = (
415
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
416
- if created
417
- else "unknown"
418
- )
370
+ created = attrs.get("Created", None)
371
+ created_str = self._parse_timestamp(created)
419
372
  result = {
420
373
  "id": attrs.get("Id", "unknown")[7:19],
421
374
  "image": attrs.get("Config", {}).get("Image", image),
@@ -430,6 +383,98 @@ class DockerManager(ContainerManagerBase):
430
383
  self.log_action("run_container", params, error=e)
431
384
  raise RuntimeError(f"Failed to run container: {str(e)}")
432
385
 
386
+ def list_networks(self) -> List[Dict]:
387
+ params = {}
388
+ try:
389
+ networks = self.client.networks.list()
390
+ result = []
391
+ for net in networks:
392
+ attrs = net.attrs
393
+ containers = len(attrs.get("Containers", {}))
394
+ created = attrs.get("Created", None)
395
+ created_str = self._parse_timestamp(created)
396
+ simplified = {
397
+ "id": attrs.get("Id", "unknown")[7:19],
398
+ "name": attrs.get("Name", "unknown"),
399
+ "driver": attrs.get("Driver", "unknown"),
400
+ "scope": attrs.get("Scope", "unknown"),
401
+ "containers": containers,
402
+ "created": created_str,
403
+ }
404
+ result.append(simplified)
405
+ self.log_action("list_networks", params, result)
406
+ return result
407
+ except Exception as e:
408
+ self.log_action("list_networks", params, error=e)
409
+ raise RuntimeError(f"Failed to list networks: {str(e)}")
410
+
411
+ def create_network(self, name: str, driver: str = "bridge") -> Dict:
412
+ params = {"name": name, "driver": driver}
413
+ try:
414
+ network = self.client.networks.create(name, driver=driver)
415
+ attrs = network.attrs
416
+ created = attrs.get("Created", None)
417
+ created_str = self._parse_timestamp(created)
418
+ result = {
419
+ "id": attrs.get("Id", "unknown")[7:19],
420
+ "name": attrs.get("Name", name),
421
+ "driver": attrs.get("Driver", driver),
422
+ "scope": attrs.get("Scope", "unknown"),
423
+ "created": created_str,
424
+ }
425
+ self.log_action("create_network", params, result)
426
+ return result
427
+ except Exception as e:
428
+ self.log_action("create_network", params, error=e)
429
+ raise RuntimeError(f"Failed to create network: {str(e)}")
430
+
431
+ def get_version(self) -> Dict:
432
+ params = {}
433
+ try:
434
+ version = self.client.version()
435
+ result = {
436
+ "version": version.get("Version", "unknown"),
437
+ "api_version": version.get("ApiVersion", "unknown"),
438
+ "os": version.get("Os", "unknown"),
439
+ "arch": version.get("Arch", "unknown"),
440
+ "build_time": version.get("BuildTime", "unknown"),
441
+ }
442
+ self.log_action("get_version", params, result)
443
+ return result
444
+ except Exception as e:
445
+ self.log_action("get_version", params, error=e)
446
+ raise RuntimeError(f"Failed to get version: {str(e)}")
447
+
448
+ def get_info(self) -> Dict:
449
+ params = {}
450
+ try:
451
+ info = self.client.info()
452
+ result = {
453
+ "containers_total": info.get("Containers", 0),
454
+ "containers_running": info.get("ContainersRunning", 0),
455
+ "images": info.get("Images", 0),
456
+ "driver": info.get("Driver", "unknown"),
457
+ "platform": f"{info.get('OperatingSystem', 'unknown')} {info.get('Architecture', 'unknown')}",
458
+ "memory_total": self._format_size(info.get("MemTotal", 0)),
459
+ "swap_total": self._format_size(info.get("SwapTotal", 0)),
460
+ }
461
+ self.log_action("get_info", params, result)
462
+ return result
463
+ except Exception as e:
464
+ self.log_action("get_info", params, error=e)
465
+ raise RuntimeError(f"Failed to get info: {str(e)}")
466
+
467
+ def remove_image(self, image: str, force: bool = False) -> Dict:
468
+ params = {"image": image, "force": force}
469
+ try:
470
+ self.client.images.remove(image, force=force)
471
+ result = {"removed": image}
472
+ self.log_action("remove_image", params, result)
473
+ return result
474
+ except Exception as e:
475
+ self.log_action("remove_image", params, error=e)
476
+ raise RuntimeError(f"Failed to remove image: {str(e)}")
477
+
433
478
  def stop_container(self, container_id: str, timeout: int = 10) -> Dict:
434
479
  params = {"container_id": container_id, "timeout": timeout}
435
480
  try:
@@ -535,65 +580,6 @@ class DockerManager(ContainerManagerBase):
535
580
  self.log_action("remove_volume", params, error=e)
536
581
  raise RuntimeError(f"Failed to remove volume: {str(e)}")
537
582
 
538
- def list_networks(self) -> List[Dict]:
539
- params = {}
540
- try:
541
- networks = self.client.networks.list()
542
- result = []
543
- for net in networks:
544
- attrs = net.attrs
545
- containers = len(attrs.get("Containers", {}))
546
- created = attrs.get("Created", "unknown")
547
- if isinstance(created, str):
548
- created_str = created
549
- else:
550
- created_str = (
551
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
552
- if created
553
- else "unknown"
554
- )
555
- simplified = {
556
- "id": attrs.get("Id", "unknown")[7:19],
557
- "name": attrs.get("Name", "unknown"),
558
- "driver": attrs.get("Driver", "unknown"),
559
- "scope": attrs.get("Scope", "unknown"),
560
- "containers": containers,
561
- "created": created_str,
562
- }
563
- result.append(simplified)
564
- self.log_action("list_networks", params, result)
565
- return result
566
- except Exception as e:
567
- self.log_action("list_networks", params, error=e)
568
- raise RuntimeError(f"Failed to list networks: {str(e)}")
569
-
570
- def create_network(self, name: str, driver: str = "bridge") -> Dict:
571
- params = {"name": name, "driver": driver}
572
- try:
573
- network = self.client.networks.create(name, driver=driver)
574
- attrs = network.attrs
575
- created = attrs.get("Created", "unknown")
576
- if isinstance(created, str):
577
- created_str = created
578
- else:
579
- created_str = (
580
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
581
- if created
582
- else "unknown"
583
- )
584
- result = {
585
- "id": attrs.get("Id", "unknown")[7:19],
586
- "name": attrs.get("Name", name),
587
- "driver": attrs.get("Driver", driver),
588
- "scope": attrs.get("Scope", "unknown"),
589
- "created": created_str,
590
- }
591
- self.log_action("create_network", params, result)
592
- return result
593
- except Exception as e:
594
- self.log_action("create_network", params, error=e)
595
- raise RuntimeError(f"Failed to create network: {str(e)}")
596
-
597
583
  def remove_network(self, network_id: str) -> Dict:
598
584
  params = {"network_id": network_id}
599
585
  try:
@@ -839,43 +825,6 @@ class PodmanManager(ContainerManagerBase):
839
825
  self.logger.error(f"Failed to connect to Podman daemon: {str(e)}")
840
826
  raise RuntimeError(f"Failed to connect to Podman: {str(e)}")
841
827
 
842
- def get_version(self) -> Dict:
843
- params = {}
844
- try:
845
- version = self.client.version()
846
- result = {
847
- "version": version.get("Version", "unknown"),
848
- "api_version": version.get("APIVersion", "unknown"),
849
- "os": version.get("Os", "unknown"),
850
- "arch": version.get("Arch", "unknown"),
851
- "build_time": version.get("BuildTime", "unknown"),
852
- }
853
- self.log_action("get_version", params, result)
854
- return result
855
- except Exception as e:
856
- self.log_action("get_version", params, error=e)
857
- raise RuntimeError(f"Failed to get version: {str(e)}")
858
-
859
- def get_info(self) -> Dict:
860
- params = {}
861
- try:
862
- info = self.client.info()
863
- host = info.get("host", {})
864
- result = {
865
- "containers_total": info.get("store", {}).get("containers", 0),
866
- "containers_running": host.get("runningContainers", 0),
867
- "images": info.get("store", {}).get("images", 0),
868
- "driver": host.get("graphDriverName", "unknown"),
869
- "platform": f"{host.get('os', 'unknown')} {host.get('arch', 'unknown')}",
870
- "memory_total": self._format_size(host.get("memTotal", 0)),
871
- "swap_total": self._format_size(host.get("swapTotal", 0)),
872
- }
873
- self.log_action("get_info", params, result)
874
- return result
875
- except Exception as e:
876
- self.log_action("get_info", params, error=e)
877
- raise RuntimeError(f"Failed to get info: {str(e)}")
878
-
879
828
  def list_images(self) -> List[Dict]:
880
829
  params = {}
881
830
  try:
@@ -888,12 +837,8 @@ class PodmanManager(ContainerManagerBase):
888
837
  repository, tag = (
889
838
  repo_tag.rsplit(":", 1) if ":" in repo_tag else ("<none>", "<none>")
890
839
  )
891
- created = attrs.get("Created", 0)
892
- created_str = (
893
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
894
- if created
895
- else "unknown"
896
- )
840
+ created = attrs.get("Created", None)
841
+ created_str = self._parse_timestamp(created)
897
842
  size_bytes = attrs.get("Size", 0)
898
843
  size_str = self._format_size(size_bytes) if size_bytes else "0B"
899
844
  simplified = {
@@ -926,12 +871,8 @@ class PodmanManager(ContainerManagerBase):
926
871
  repository, tag = (
927
872
  repo_tag.rsplit(":", 1) if ":" in repo_tag else (image, tag)
928
873
  )
929
- created = attrs.get("Created", 0)
930
- created_str = (
931
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
932
- if created
933
- else "unknown"
934
- )
874
+ created = attrs.get("Created", None)
875
+ created_str = self._parse_timestamp(created)
935
876
  size_bytes = attrs.get("Size", 0)
936
877
  size_str = self._format_size(size_bytes) if size_bytes else "0B"
937
878
  result = {
@@ -949,17 +890,6 @@ class PodmanManager(ContainerManagerBase):
949
890
  self.log_action("pull_image", params, error=e)
950
891
  raise RuntimeError(f"Failed to pull image: {str(e)}")
951
892
 
952
- def remove_image(self, image: str, force: bool = False) -> Dict:
953
- params = {"image": image, "force": force}
954
- try:
955
- self.client.images.remove(image, force=force)
956
- result = {"removed": image}
957
- self.log_action("remove_image", params, result)
958
- return result
959
- except Exception as e:
960
- self.log_action("remove_image", params, error=e)
961
- raise RuntimeError(f"Failed to remove image: {str(e)}")
962
-
963
893
  def list_containers(self, all: bool = False) -> List[Dict]:
964
894
  params = {"all": all}
965
895
  try:
@@ -973,12 +903,8 @@ class PodmanManager(ContainerManagerBase):
973
903
  for p in ports
974
904
  if p.get("host_port")
975
905
  ]
976
- created = attrs.get("Created", 0)
977
- created_str = (
978
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
979
- if created
980
- else "unknown"
981
- )
906
+ created = attrs.get("Created", None)
907
+ created_str = self._parse_timestamp(created)
982
908
  simplified = {
983
909
  "id": attrs.get("Id", "unknown")[7:19],
984
910
  "image": attrs.get("Image", "unknown"),
@@ -1034,12 +960,8 @@ class PodmanManager(ContainerManagerBase):
1034
960
  for p in ports
1035
961
  if p.get("host_port")
1036
962
  ]
1037
- created = attrs.get("Created", 0)
1038
- created_str = (
1039
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
1040
- if created
1041
- else "unknown"
1042
- )
963
+ created = attrs.get("Created", None)
964
+ created_str = self._parse_timestamp(created)
1043
965
  result = {
1044
966
  "id": attrs.get("Id", "unknown")[7:19],
1045
967
  "image": attrs.get("Image", image),
@@ -1054,6 +976,99 @@ class PodmanManager(ContainerManagerBase):
1054
976
  self.log_action("run_container", params, error=e)
1055
977
  raise RuntimeError(f"Failed to run container: {str(e)}")
1056
978
 
979
+ def list_networks(self) -> List[Dict]:
980
+ params = {}
981
+ try:
982
+ networks = self.client.networks.list()
983
+ result = []
984
+ for net in networks:
985
+ attrs = net.attrs
986
+ containers = len(attrs.get("Containers", {}))
987
+ created = attrs.get("Created", None)
988
+ created_str = self._parse_timestamp(created)
989
+ simplified = {
990
+ "id": attrs.get("Id", "unknown")[7:19],
991
+ "name": attrs.get("Name", "unknown"),
992
+ "driver": attrs.get("Driver", "unknown"),
993
+ "scope": attrs.get("Scope", "unknown"),
994
+ "containers": containers,
995
+ "created": created_str,
996
+ }
997
+ result.append(simplified)
998
+ self.log_action("list_networks", params, result)
999
+ return result
1000
+ except Exception as e:
1001
+ self.log_action("list_networks", params, error=e)
1002
+ raise RuntimeError(f"Failed to list networks: {str(e)}")
1003
+
1004
+ def create_network(self, name: str, driver: str = "bridge") -> Dict:
1005
+ params = {"name": name, "driver": driver}
1006
+ try:
1007
+ network = self.client.networks.create(name, driver=driver)
1008
+ attrs = network.attrs
1009
+ created = attrs.get("Created", None)
1010
+ created_str = self._parse_timestamp(created)
1011
+ result = {
1012
+ "id": attrs.get("Id", "unknown")[7:19],
1013
+ "name": attrs.get("Name", name),
1014
+ "driver": attrs.get("Driver", driver),
1015
+ "scope": attrs.get("Scope", "unknown"),
1016
+ "created": created_str,
1017
+ }
1018
+ self.log_action("create_network", params, result)
1019
+ return result
1020
+ except Exception as e:
1021
+ self.log_action("create_network", params, error=e)
1022
+ raise RuntimeError(f"Failed to create network: {str(e)}")
1023
+
1024
+ def get_version(self) -> Dict:
1025
+ params = {}
1026
+ try:
1027
+ version = self.client.version()
1028
+ result = {
1029
+ "version": version.get("Version", "unknown"),
1030
+ "api_version": version.get("APIVersion", "unknown"),
1031
+ "os": version.get("Os", "unknown"),
1032
+ "arch": version.get("Arch", "unknown"),
1033
+ "build_time": version.get("BuildTime", "unknown"),
1034
+ }
1035
+ self.log_action("get_version", params, result)
1036
+ return result
1037
+ except Exception as e:
1038
+ self.log_action("get_version", params, error=e)
1039
+ raise RuntimeError(f"Failed to get version: {str(e)}")
1040
+
1041
+ def get_info(self) -> Dict:
1042
+ params = {}
1043
+ try:
1044
+ info = self.client.info()
1045
+ host = info.get("host", {})
1046
+ result = {
1047
+ "containers_total": info.get("store", {}).get("containers", 0),
1048
+ "containers_running": host.get("runningContainers", 0),
1049
+ "images": info.get("store", {}).get("images", 0),
1050
+ "driver": host.get("graphDriverName", "unknown"),
1051
+ "platform": f"{host.get('os', 'unknown')} {host.get('arch', 'unknown')}",
1052
+ "memory_total": self._format_size(host.get("memTotal", 0)),
1053
+ "swap_total": self._format_size(host.get("swapTotal", 0)),
1054
+ }
1055
+ self.log_action("get_info", params, result)
1056
+ return result
1057
+ except Exception as e:
1058
+ self.log_action("get_info", params, error=e)
1059
+ raise RuntimeError(f"Failed to get info: {str(e)}")
1060
+
1061
+ def remove_image(self, image: str, force: bool = False) -> Dict:
1062
+ params = {"image": image, "force": force}
1063
+ try:
1064
+ self.client.images.remove(image, force=force)
1065
+ result = {"removed": image}
1066
+ self.log_action("remove_image", params, result)
1067
+ return result
1068
+ except Exception as e:
1069
+ self.log_action("remove_image", params, error=e)
1070
+ raise RuntimeError(f"Failed to remove image: {str(e)}")
1071
+
1057
1072
  def stop_container(self, container_id: str, timeout: int = 10) -> Dict:
1058
1073
  params = {"container_id": container_id, "timeout": timeout}
1059
1074
  try:
@@ -1159,65 +1174,6 @@ class PodmanManager(ContainerManagerBase):
1159
1174
  self.log_action("remove_volume", params, error=e)
1160
1175
  raise RuntimeError(f"Failed to remove volume: {str(e)}")
1161
1176
 
1162
- def list_networks(self) -> List[Dict]:
1163
- params = {}
1164
- try:
1165
- networks = self.client.networks.list()
1166
- result = []
1167
- for net in networks:
1168
- attrs = net.attrs
1169
- containers = len(attrs.get("Containers", {}))
1170
- created = attrs.get("Created", "unknown")
1171
- if isinstance(created, str):
1172
- created_str = created
1173
- else:
1174
- created_str = (
1175
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
1176
- if created
1177
- else "unknown"
1178
- )
1179
- simplified = {
1180
- "id": attrs.get("Id", "unknown")[7:19],
1181
- "name": attrs.get("Name", "unknown"),
1182
- "driver": attrs.get("Driver", "unknown"),
1183
- "scope": attrs.get("Scope", "unknown"),
1184
- "containers": containers,
1185
- "created": created_str,
1186
- }
1187
- result.append(simplified)
1188
- self.log_action("list_networks", params, result)
1189
- return result
1190
- except Exception as e:
1191
- self.log_action("list_networks", params, error=e)
1192
- raise RuntimeError(f"Failed to list networks: {str(e)}")
1193
-
1194
- def create_network(self, name: str, driver: str = "bridge") -> Dict:
1195
- params = {"name": name, "driver": driver}
1196
- try:
1197
- network = self.client.networks.create(name, driver=driver)
1198
- attrs = network.attrs
1199
- created = attrs.get("Created", "unknown")
1200
- if isinstance(created, str):
1201
- created_str = created
1202
- else:
1203
- created_str = (
1204
- datetime.fromtimestamp(created).strftime("%Y-%m-%dT%H:%M:%S")
1205
- if created
1206
- else "unknown"
1207
- )
1208
- result = {
1209
- "id": attrs.get("Id", "unknown")[7:19],
1210
- "name": attrs.get("Name", name),
1211
- "driver": attrs.get("Driver", driver),
1212
- "scope": attrs.get("Scope", "unknown"),
1213
- "created": created_str,
1214
- }
1215
- self.log_action("create_network", params, result)
1216
- return result
1217
- except Exception as e:
1218
- self.log_action("create_network", params, error=e)
1219
- raise RuntimeError(f"Failed to create network: {str(e)}")
1220
-
1221
1177
  def remove_network(self, network_id: str) -> Dict:
1222
1178
  params = {"network_id": network_id}
1223
1179
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: container-manager-mcp
3
- Version: 0.0.11
3
+ Version: 0.0.12
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: 0.0.11*
51
+ *Version: 0.0.12*
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
 
@@ -0,0 +1,10 @@
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=hIdXyI7L2kFrJc_7bMOaQpKAPECxCVjaQoohqjmY-Iw,67859
4
+ container_manager_mcp/container_manager_mcp.py,sha256=cIAN8YGflQ9nZEHodkYdQKo2GECAuTH7WB-oMhnAd_0,37959
5
+ container_manager_mcp-0.0.12.dist-info/licenses/LICENSE,sha256=Z1xmcrPHBnGCETO_LLQJUeaSNBSnuptcDVTt4kaPUOE,1060
6
+ container_manager_mcp-0.0.12.dist-info/METADATA,sha256=ItKjQvWeRj9e8J26zMjGilRfuFPywXf6afihA_knBdA,8240
7
+ container_manager_mcp-0.0.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ container_manager_mcp-0.0.12.dist-info/entry_points.txt,sha256=I23pXcCgAShlfYbENzs3kbw3l1lU9Gy7lODPfRqeeiA,156
9
+ container_manager_mcp-0.0.12.dist-info/top_level.txt,sha256=B7QQLOd9mBdu0lsPKqyu4T8-zUtbqKzQJbMbtAzoozU,22
10
+ container_manager_mcp-0.0.12.dist-info/RECORD,,
@@ -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=64pDF7gEadqh_rVqjfkznLSWm6fFnZJJ5hnkZlgX9kI,69338
4
- container_manager_mcp/container_manager_mcp.py,sha256=cIAN8YGflQ9nZEHodkYdQKo2GECAuTH7WB-oMhnAd_0,37959
5
- container_manager_mcp-0.0.11.dist-info/licenses/LICENSE,sha256=Z1xmcrPHBnGCETO_LLQJUeaSNBSnuptcDVTt4kaPUOE,1060
6
- container_manager_mcp-0.0.11.dist-info/METADATA,sha256=bQQ_l-V1ZAh5ciFG00U0hLIqttSm45RjO_9Va7DKinU,8240
7
- container_manager_mcp-0.0.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- container_manager_mcp-0.0.11.dist-info/entry_points.txt,sha256=I23pXcCgAShlfYbENzs3kbw3l1lU9Gy7lODPfRqeeiA,156
9
- container_manager_mcp-0.0.11.dist-info/top_level.txt,sha256=B7QQLOd9mBdu0lsPKqyu4T8-zUtbqKzQJbMbtAzoozU,22
10
- container_manager_mcp-0.0.11.dist-info/RECORD,,