|
10 | 10 | import lombok.NonNull; |
11 | 11 | import lombok.RequiredArgsConstructor; |
12 | 12 | import lombok.experimental.FieldDefaults; |
| 13 | +import org.apache.commons.io.FileUtils; |
13 | 14 | import org.jspecify.annotations.Nullable; |
14 | 15 |
|
15 | 16 | import java.io.*; |
@@ -66,11 +67,6 @@ public boolean leaveSwarmCmd(boolean force) { |
66 | 67 | return true; |
67 | 68 | } |
68 | 69 |
|
69 | | - // not supported |
70 | | - public AttachContainerCmd attachContainerCmd(@NonNull String containerId) { |
71 | | - return internalClient.attachContainerCmd(containerId); |
72 | | - } |
73 | | - |
74 | 70 | @McpTool(name = "docker_container_diff", |
75 | 71 | description = "List changes made to a container's filesystem since creation. " + |
76 | 72 | "Shows added (A), deleted (D), and changed (C) files. containerId is required and can't be null " + |
@@ -767,50 +763,191 @@ public CreateContainerCmd createContainerCmd( |
767 | 763 | return cmd; |
768 | 764 | } |
769 | 765 |
|
770 | | - public BuildImageCmd buildImageCmd(InputStream tarInputStream) { |
771 | | - return internalClient.buildImageCmd(tarInputStream); |
772 | | - } |
| 766 | + @McpTool( |
| 767 | + name = "docker_load_image", |
| 768 | + description = """ |
| 769 | + Loads a Docker image from a provided tar file absolute address. |
773 | 770 |
|
774 | | - public LoadImageCmd loadImageCmd(InputStream imageStream) { |
775 | | - return internalClient.loadImageCmd(imageStream); |
776 | | - } |
| 771 | + This command allows you to import a Docker image that has been saved using `docker save`, or any compatible image tarball, |
| 772 | + directly into the Docker engine. This is useful for scenarios where the image is obtained from a file, network, or remote source |
| 773 | + and not directly from a registry. |
777 | 774 |
|
778 | | - public ListTasksCmd listTasksCmd() { |
779 | | - return internalClient.listTasksCmd(); |
780 | | - } |
| 775 | + Parameters: |
| 776 | + - tarFile: (String, required) The input tar file absolute address. |
781 | 777 |
|
782 | | - public SaveImagesCmd saveImagesCmd() { |
783 | | - return internalClient.saveImagesCmd(); |
| 778 | + Returns: |
| 779 | + - true if successfully loaded the image |
| 780 | + """ |
| 781 | + ) |
| 782 | + public boolean loadImageCmd(String tarFile) throws FileNotFoundException { |
| 783 | + internalClient.loadImageCmd(new FileInputStream(tarFile)) |
| 784 | + .exec(); |
| 785 | + return true; |
784 | 786 | } |
785 | 787 |
|
786 | | - public JoinSwarmCmd joinSwarmCmd() { |
787 | | - return internalClient.joinSwarmCmd(); |
| 788 | + @McpTool( |
| 789 | + name = "docker_list_tasks", |
| 790 | + description = """ |
| 791 | + Lists the tasks in a Docker Swarm environment. |
| 792 | +
|
| 793 | + This command retrieves all the tasks currently known to the Docker engine. Tasks are the individual units of work |
| 794 | + in a Swarm service, each representing a running container instance. This is especially useful for monitoring, |
| 795 | + debugging, or inspecting the current state of services in a Swarm cluster. |
| 796 | +
|
| 797 | + Parameters: |
| 798 | + - None |
| 799 | +
|
| 800 | + Returns: |
| 801 | + - (List<Task>) A list of Task objects representing running or completed tasks within the Swarm environment. |
| 802 | + """ |
| 803 | + ) |
| 804 | + public List<Task> listTasksCmd() { |
| 805 | + return internalClient.listTasksCmd() |
| 806 | + .exec(); |
788 | 807 | } |
789 | 808 |
|
790 | | - public CreateVolumeCmd createVolumeCmd() { |
791 | | - return internalClient.createVolumeCmd(); |
| 809 | + @McpTool( |
| 810 | + name = "docker_save_image", |
| 811 | + description = """ |
| 812 | + Saves a Docker image to a local tar file. |
| 813 | +
|
| 814 | + This command exports a specified Docker image (with an optional tag) to a tar archive on the local filesystem. |
| 815 | + This is useful for backing up images, transferring them between systems, or archiving versions for reproducibility. |
| 816 | +
|
| 817 | + Parameters: |
| 818 | + - imageName: (String, required) The name of the Docker image to save. |
| 819 | + - imageTag: (String, required) The tag of the image to save (e.g., "latest"). |
| 820 | + - tarFileAbsolutePath: (String, required) The full absolute path where the resulting tar file should be saved. |
| 821 | +
|
| 822 | + Returns: |
| 823 | + - (boolean) true if the image is successfully saved to the specified file. |
| 824 | + |
| 825 | + Throws: |
| 826 | + - IOException if writing to the target file fails or if the image stream cannot be read. |
| 827 | + """ |
| 828 | + ) |
| 829 | + public boolean saveImagesCmd(String imageName, String imageTag, String tarFileAbsolutePath) throws IOException { |
| 830 | + InputStream stream = internalClient.saveImagesCmd() |
| 831 | + .withImage(imageName, imageTag) |
| 832 | + .exec(); |
| 833 | + |
| 834 | + File targetFile = new File(tarFileAbsolutePath); |
| 835 | + |
| 836 | + FileUtils.copyInputStreamToFile(stream, targetFile); |
| 837 | + |
| 838 | + return true; |
792 | 839 | } |
793 | 840 |
|
794 | | - public BuildImageCmd buildImageCmd() { |
795 | | - return internalClient.buildImageCmd(); |
| 841 | + @McpTool( |
| 842 | + name = "docker_join_swarm", |
| 843 | + description = """ |
| 844 | + Joins the current Docker node to an existing Swarm cluster. |
| 845 | +
|
| 846 | + This command configures the node to join an existing Docker Swarm cluster using the provided advertise address, join token, and remote manager addresses. |
| 847 | +
|
| 848 | + Parameters: |
| 849 | + - advertiseAddr: (String, optional) The address advertised to other nodes in the cluster. This should be reachable by other Swarm nodes. |
| 850 | + - joinToken: (String, optional) The Swarm join token. Required for joining as a worker or manager. |
| 851 | + - remoteAddrs: (List<String>, optional) A list of manager node addresses to connect to during the join operation. |
| 852 | +
|
| 853 | + Returns: |
| 854 | + - (boolean) true if the node successfully joins the Swarm. |
| 855 | +
|
| 856 | + Notes: |
| 857 | + - If `advertiseAddr` or `joinToken` are not provided, Docker's default behavior applies. |
| 858 | + - All `null` entries in `remoteAddrs` are ignored. |
| 859 | + """ |
| 860 | + ) |
| 861 | + public boolean joinSwarmCmd(String advertiseAddr, String joinToken, List<String> remoteAddrs) { |
| 862 | + JoinSwarmCmd cmd = internalClient.joinSwarmCmd(); |
| 863 | + if (advertiseAddr != null && !advertiseAddr.isBlank()) { |
| 864 | + cmd.withAdvertiseAddr(advertiseAddr); |
| 865 | + } |
| 866 | + |
| 867 | + if (joinToken != null && !joinToken.isBlank()) { |
| 868 | + cmd.withJoinToken(joinToken); |
| 869 | + } |
| 870 | + |
| 871 | + if (remoteAddrs != null) { |
| 872 | + cmd.withRemoteAddrs(remoteAddrs.stream().filter(Objects::nonNull).toList()); |
| 873 | + } |
| 874 | + |
| 875 | + cmd.exec(); |
| 876 | + |
| 877 | + return true; |
796 | 878 | } |
797 | 879 |
|
798 | | - public SaveImageCmd saveImageCmd(String name) { |
799 | | - return internalClient.saveImageCmd(name); |
| 880 | + @McpTool( |
| 881 | + name = "docker_create_volume", |
| 882 | + description = """ |
| 883 | + Creates a new Docker volume with optional configurations. |
| 884 | +
|
| 885 | + This command creates a volume that can later be mounted into containers. You can configure the volume's name, driver, driver options, and labels. |
| 886 | +
|
| 887 | + Parameters: |
| 888 | + - name: (String, optional) The name of the volume. If not specified, Docker will generate a unique name. |
| 889 | + - driver: (String, optional) Volume driver to use. Defaults to 'local'. |
| 890 | + - driverOpts: (Map<String, String>, optional) A map of driver-specific options passed during volume creation. |
| 891 | + - labels: (Map<String, String>, optional) Labels to set on the volume for identification and management. |
| 892 | +
|
| 893 | + Returns: |
| 894 | + - (CreateVolumeResponse) The response containing details about the created volume. |
| 895 | + """ |
| 896 | + ) |
| 897 | + public CreateVolumeResponse createVolumeCmd( |
| 898 | + String name, |
| 899 | + String driver, |
| 900 | + Map<String, String> driverOpts, |
| 901 | + Map<String, String> labels |
| 902 | + ) { |
| 903 | + try(CreateVolumeCmd cmd = internalClient.createVolumeCmd()) { |
| 904 | + |
| 905 | + if (name != null && !name.isBlank()) { |
| 906 | + cmd.withName(name); |
| 907 | + } |
| 908 | + |
| 909 | + if (driver != null && !driver.isBlank()) { |
| 910 | + cmd.withDriver(driver); |
| 911 | + } |
| 912 | + |
| 913 | + if (driverOpts != null && !driverOpts.isEmpty()) { |
| 914 | + cmd.withDriverOpts(driverOpts); |
| 915 | + } |
| 916 | + |
| 917 | + if (labels != null && !labels.isEmpty()) { |
| 918 | + cmd.withLabels(labels); |
| 919 | + } |
| 920 | + |
| 921 | + return cmd.exec(); |
| 922 | + } |
800 | 923 | } |
801 | 924 |
|
802 | | - public InitializeSwarmCmd initializeSwarmCmd(SwarmSpec swarmSpec) { |
803 | | - return internalClient.initializeSwarmCmd(swarmSpec); |
| 925 | + @McpTool( |
| 926 | + name = "docker_initialize_swarm", |
| 927 | + description = """ |
| 928 | + Initializes a new Docker Swarm cluster with the given configuration. |
| 929 | +
|
| 930 | + This command sets up the current Docker Engine as a manager node in a new Swarm cluster using the provided Swarm specification. |
| 931 | +
|
| 932 | + Parameters: |
| 933 | + - swarmSpec: (SwarmSpec, required) Specification for initializing the swarm. It includes information like the orchestration, dispatcher, CA configuration, encryption, and Raft configuration. |
| 934 | + - forceNewCluster: (boolean, required) If true, forces the creation of a new cluster even if one already exists. |
| 935 | +
|
| 936 | + Returns: |
| 937 | + - (boolean) True if the initialization was successful. |
| 938 | + """ |
| 939 | + ) |
| 940 | + public boolean initializeSwarmCmd(SwarmSpec swarmSpec, boolean forceNewCluster) { |
| 941 | + internalClient.initializeSwarmCmd(swarmSpec) |
| 942 | + .withForceNewCluster(forceNewCluster) |
| 943 | + .exec(); |
| 944 | + return true; |
804 | 945 | } |
805 | 946 |
|
806 | 947 | public UpdateServiceCmd updateServiceCmd(String serviceId, ServiceSpec serviceSpec) { |
807 | 948 | return internalClient.updateServiceCmd(serviceId, serviceSpec); |
808 | 949 | } |
809 | 950 |
|
810 | | - public CommitCmd commitCmd(String containerId) { |
811 | | - return internalClient.commitCmd(containerId); |
812 | | - } |
813 | | - |
814 | 951 | public ListConfigsCmd listConfigsCmd() { |
815 | 952 | return internalClient.listConfigsCmd(); |
816 | 953 | } |
@@ -841,7 +978,7 @@ public CreateServiceCmd createServiceCmd(ServiceSpec serviceSpec) { |
841 | 978 | Removes a Docker network. |
842 | 979 |
|
843 | 980 | This command removes a specified Docker network. The network must not be in use by any containers |
844 | | - at the time of removal. If containers are using the network, they must be disconnected before the |
| 981 | + at the time of removal. If containers are using the network, they must be disconnected before the |
845 | 982 | network can be removed. |
846 | 983 |
|
847 | 984 | Parameters: |
|
0 commit comments