docker_mcp 0.2.5 → 0.3.0

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.
@@ -3,161 +3,107 @@
3
3
  module DockerMCP
4
4
  # MCP tool for tagging Docker images.
5
5
  #
6
- # This tool provides the ability to create new tags for existing Docker images,
7
- # enabling better organization, versioning, and distribution of images. Tags
8
- # are essential for image management and registry operations.
6
+ # This tool provides the ability to assign repository names and tags
7
+ # to Docker images. Tagging is essential for image organization,
8
+ # versioning, and distribution through Docker registries.
9
9
  #
10
10
  # == Features
11
11
  #
12
- # - Tag images by ID or existing name
13
- # - Support for repository and tag specification
12
+ # - Tag existing images with custom repository names
13
+ # - Support for version and environment tags
14
14
  # - Force tagging to overwrite existing tags
15
- # - Registry-compatible tag formatting
16
- # - Comprehensive error handling
17
- # - Multiple tags per image support
18
- #
19
- # == Tag Management Benefits
20
- #
21
- # Proper tagging enables:
22
- # - **Version Control**: Track different image versions
23
- # - **Distribution**: Prepare images for registry push
24
- # - **Organization**: Group related images logically
25
- # - **Deployment**: Reference specific image versions
26
- # - **Rollback**: Maintain previous versions for rollback
15
+ # - Registry-compatible naming conventions
16
+ # - Automatic tag defaulting to "latest"
17
+ # - Comprehensive error handling and validation
27
18
  #
28
19
  # == Security Considerations
29
20
  #
30
- # Tagging affects image accessibility and distribution:
31
- # - Tags determine registry push destinations
32
- # - Overwriting tags can affect running containers
33
- # - Registry-compatible tags expose images for distribution
34
- # - Tag names may reveal application details
21
+ # Image tagging involves several security considerations:
22
+ # - **Registry Authentication**: Tags may trigger registry operations
23
+ # - **Namespace Conflicts**: Overwriting tags can affect other deployments
24
+ # - **Image Identity**: Improper tagging can lead to deployment confusion
25
+ # - **Version Management**: Incorrect tags can compromise CI/CD pipelines
26
+ # - **Registry Pollution**: Excessive tagging can clutter registries
35
27
  #
36
- # Best practices:
37
- # - Use descriptive but not sensitive tag names
38
- # - Avoid overwriting production tags accidentally
39
- # - Implement tag naming conventions
40
- # - Regular cleanup of unused tags
41
- # - Control access to critical tag operations
28
+ # **Security Recommendations**:
29
+ # - Use consistent naming conventions
30
+ # - Implement tag governance policies
31
+ # - Verify image identity before tagging
32
+ # - Avoid overwriting production tags
33
+ # - Use semantic versioning for releases
34
+ # - Monitor tag usage and lifecycle
42
35
  #
43
- # == Tag Naming Conventions
36
+ # == Parameters
44
37
  #
45
- # Recommended patterns:
46
- # - **Semantic Versioning**: `v1.2.3`, `1.2.3-alpha`
47
- # - **Environment Tags**: `prod`, `staging`, `dev`
48
- # - **Feature Tags**: `feature-branch-name`
49
- # - **Date Tags**: `2024-01-15`, `20240115`
50
- # - **Commit Tags**: `sha-abc123def`
38
+ # - **id**: Image ID or current name:tag to tag (required)
39
+ # - **repo**: Repository name (required, e.g., "username/imagename" or "registry/username/imagename")
40
+ # - **tag**: Tag for the image (optional, default: "latest")
41
+ # - **force**: Force tag even if it already exists (optional, default: true)
51
42
  #
52
43
  # == Example Usage
53
44
  #
54
- # # Tag with version
55
- # TagImage.call(
45
+ # # Tag image with version
46
+ # response = TagImage.call(
56
47
  # server_context: context,
57
- # id: "abc123def456",
58
- # repo: "myapp",
59
- # tag: "v1.0.0"
48
+ # id: "myapp:dev",
49
+ # repo: "myregistry/myapp",
50
+ # tag: "v1.2.3"
60
51
  # )
61
52
  #
62
- # # Tag for registry push
63
- # TagImage.call(
53
+ # # Tag for production deployment
54
+ # response = TagImage.call(
64
55
  # server_context: context,
65
- # id: "myapp:latest",
66
- # repo: "myusername/myapp",
67
- # tag: "production"
56
+ # id: "abc123def456",
57
+ # repo: "production/webapp",
58
+ # tag: "stable",
59
+ # force: false
68
60
  # )
69
61
  #
70
- # # Tag for private registry
71
- # TagImage.call(
62
+ # # Tag with registry prefix
63
+ # response = TagImage.call(
72
64
  # server_context: context,
73
- # id: "webapp:dev",
74
- # repo: "registry.company.com/team/webapp",
75
- # tag: "v2.1.0"
65
+ # id: "local-build:latest",
66
+ # repo: "registry.company.com/team/service",
67
+ # tag: "release-candidate"
76
68
  # )
77
69
  #
78
- # @see BuildImage
79
- # @see PushImage
80
70
  # @see Docker::Image#tag
81
71
  # @since 0.1.0
82
- class TagImage < MCP::Tool
72
+ TAG_IMAGE_DEFINITION = ToolForge.define(:tag_image) do
83
73
  description 'Tag a Docker image'
84
74
 
85
- input_schema(
86
- properties: {
87
- id: {
88
- type: 'string',
89
- description: 'Image ID or current name:tag'
90
- },
91
- repo: {
92
- type: 'string',
75
+ param :id,
76
+ type: :string,
77
+ description: 'Image ID or current name:tag to tag'
78
+
79
+ param :repo,
80
+ type: :string,
93
81
  description: 'Repository name (e.g., "username/imagename" or "registry/username/imagename")'
94
- },
95
- tag: {
96
- type: 'string',
97
- description: 'Tag for the image (default: "latest")'
98
- },
99
- force: {
100
- type: 'boolean',
101
- description: 'Force tag even if it already exists (default: true)'
102
- }
103
- },
104
- required: %w[id repo]
105
- )
106
82
 
107
- # Tag a Docker image with a new repository and tag name.
108
- #
109
- # This method creates a new tag for an existing image, allowing it to
110
- # be referenced by the new name. This is essential for organizing images
111
- # and preparing them for registry distribution.
112
- #
113
- # @param id [String] image ID or current name:tag to tag
114
- # @param repo [String] repository name for the new tag
115
- # @param server_context [Object] MCP server context (unused but required)
116
- # @param tag [String] tag name for the image (default: "latest")
117
- # @param force [Boolean] whether to overwrite existing tags (default: true)
118
- #
119
- # @return [MCP::Tool::Response] tagging operation results
120
- #
121
- # @raise [Docker::Error::NotFoundError] if source image doesn't exist
122
- # @raise [StandardError] for other tagging failures
123
- #
124
- # @example Tag for versioning
125
- # response = TagImage.call(
126
- # server_context: context,
127
- # id: "my-app:latest",
128
- # repo: "my-app",
129
- # tag: "v1.2.3"
130
- # )
131
- #
132
- # @example Tag for registry push
133
- # response = TagImage.call(
134
- # server_context: context,
135
- # id: "abc123def456",
136
- # repo: "myregistry.com/myuser/myapp",
137
- # tag: "production",
138
- # force: true
139
- # )
140
- #
141
- # @see Docker::Image#tag
142
- def self.call(id:, repo:, server_context:, tag: 'latest', force: true)
83
+ param :tag,
84
+ type: :string,
85
+ description: 'Tag for the image (default: "latest")',
86
+ required: false,
87
+ default: 'latest'
88
+
89
+ param :force,
90
+ type: :boolean,
91
+ description: 'Force tag even if it already exists (default: true)',
92
+ required: false,
93
+ default: true
94
+
95
+ execute do |id:, repo:, tag: 'latest', force: true|
143
96
  image = Docker::Image.get(id)
144
97
 
145
98
  image.tag('repo' => repo, 'tag' => tag, 'force' => force)
146
99
 
147
- MCP::Tool::Response.new([{
148
- type: 'text',
149
- text: "Image tagged successfully as #{repo}:#{tag}"
150
- }])
100
+ "Image tagged successfully as #{repo}:#{tag}"
151
101
  rescue Docker::Error::NotFoundError
152
- MCP::Tool::Response.new([{
153
- type: 'text',
154
- text: "Image #{id} not found"
155
- }])
102
+ "Image #{id} not found"
156
103
  rescue StandardError => e
157
- MCP::Tool::Response.new([{
158
- type: 'text',
159
- text: "Error tagging image: #{e.message}"
160
- }])
104
+ "Error tagging image: #{e.message}"
161
105
  end
162
106
  end
107
+
108
+ TagImage = TAG_IMAGE_DEFINITION.to_mcp_tool
163
109
  end
@@ -10,5 +10,5 @@ module DockerMCP
10
10
  #
11
11
  # @see https://semver.org/
12
12
  # @since 0.1.0
13
- VERSION = '0.2.5'
13
+ VERSION = '0.3.0'
14
14
  end
data/lib/docker_mcp.rb CHANGED
@@ -3,9 +3,11 @@
3
3
  require 'docker'
4
4
  require 'json'
5
5
  require 'mcp'
6
+ require 'open3'
6
7
  require 'rubygems/package'
7
8
  require 'shellwords'
8
9
  require 'stringio'
10
+ require 'tool_forge'
9
11
  require 'zeitwerk'
10
12
 
11
13
  loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker_mcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron F Stanton
@@ -51,6 +51,20 @@ dependencies:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: tool_forge
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: zeitwerk
56
70
  requirement: !ruby/object:Gem::Requirement