Implement getBuildArtifacts tool and optimize getBuild response - #42
Implement getBuildArtifacts tool and optimize getBuild response#42dt-atmosic wants to merge 10 commits into
Conversation
- Add BuildArtifactsExtension with getBuildArtifacts and getBuildArtifact tools - Create RunWithoutArtifactsSerializer to exclude artifacts from getBuild responses - Add comprehensive tests for new functionality - Implement pagination support for large artifact files - Maintain backward compatibility while reducing payload sizes Addresses first part of issue jenkinsci#32: separate artifacts retrieval from build metadata
- Replace Java record with regular class for Java 11 compatibility - Fix regex pattern in RunWithoutArtifactsSerializer with DOTALL flag - Update test methods to use proper McpSchema.TextContent pattern - Remove non-existent TestUtils.getTextContent() method calls - Follow existing test patterns from the codebase
- Declare ObjectMapper inside lambda scope where it's used - Resolves compilation error in GetBuildWithoutArtifactsTest.java
- Use record for BuildArtifactResponse - Use TreePruner - spotless:apply
|
Working on the code coverage warnings. |
| * - "unchecked": Run.getArtifacts() returns raw List requiring unchecked conversion | ||
| */ | ||
| @SuppressWarnings({"rawtypes", "unchecked"}) | ||
| @Tool(description = "Get the artifacts for a specific build or the last build of a Jenkins job") |
There was a problem hiding this comment.
will need annotations = @Tool.Annotations(destructiveHint = false)
as it's true per default
There was a problem hiding this comment.
Done — added annotations = @Tool.Annotations(destructiveHint = false) to getBuildArtifacts.
| .orElse(List.of()); | ||
| } | ||
|
|
||
| @Tool( |
There was a problem hiding this comment.
will need annotations = @Tool.Annotations(destructiveHint = false)
as it's true per default
There was a problem hiding this comment.
Done — added annotations = @Tool.Annotations(destructiveHint = false) to getBuildArtifact as well.
| offset = 0L; | ||
| } | ||
| if (limit == null || limit <= 0) { | ||
| limit = 65536; // 64KB default |
There was a problem hiding this comment.
might be better having a configuration (e.g SystemProperties) as users may want to configure more or less.
There was a problem hiding this comment.
Done. The default is now read from a system property: SystemProperties.getInteger("io.jenkins.plugins.mcp.server.extensions.BuildArtifactsExtension.limit.default", 65536), so it still defaults to 64KB but can be tuned.
| } | ||
|
|
||
| // Cap the limit to prevent excessive memory usage | ||
| final int maxLimit = 1048576; // 1MB max |
There was a problem hiding this comment.
same here. should be configurable
There was a problem hiding this comment.
Done. The cap is now SystemProperties.getInteger("io.jenkins.plugins.mcp.server.extensions.BuildArtifactsExtension.limit.max", 1048576) — defaults to 1MB, configurable.
| } | ||
| // Serialize all results the same way - this fixes the JSON concatenation issue | ||
| // for top-level lists while maintaining proper JSON structure | ||
| resultBuilder.addTextContent(toJson(result)); |
There was a problem hiding this comment.
Agreed. I've merged the latest main, which includes the ToolResponse refactor from #82. I dropped this local toMcpResult change in favor of upstream's implementation, so list/single results are now handled consistently there.
| } else { | ||
| resultBuilder.addTextContent(toJson(result)); | ||
| } | ||
| // Serialize all results the same way - this fixes the JSON concatenation issue |
There was a problem hiding this comment.
no need of this comment here.
it;s more a PR comment :)
There was a problem hiding this comment.
Removed — this whole toMcpResult change was reverted in favor of upstream's ToolResponse (#82), so the comment no longer exists.
| } | ||
|
|
||
| // Convert to string (assuming text content) | ||
| String content = new String(buffer, 0, bytesRead, StandardCharsets.UTF_8); |
There was a problem hiding this comment.
what about binaries artifacts? (we can attach jar, war etc....)
There was a problem hiding this comment.
Good point. getBuildArtifact now detects binary content (NUL-byte sniff over the read buffer) and returns a clear message — "Artifact appears to be binary and cannot be returned as text: " — instead of emitting garbled UTF-8. getBuildArtifacts still lists every artifact (binary or not) for discovery. Added test coverage in testGetBuildArtifactBinary. Let me know if you'd prefer base64 streaming instead.
…EZXC06JZW1B # Conflicts: # README.md # src/main/java/io/jenkins/plugins/mcp/server/tool/McpToolWrapper.java # src/test/java/io/jenkins/plugins/mcp/server/EndPointTest.java # src/test/java/io/jenkins/plugins/mcp/server/extensions/DefaultMcpServerTest.java
… tree-prune compat
- Add @Tool.Annotations(destructiveHint=false) to getBuildArtifacts/getBuildArtifact
- Make default/max artifact size limits configurable via SystemProperties
- Detect binary artifacts and refuse with a clear message instead of garbled text
- Rework RunWithoutArtifactsSerializer to honor the upstream 'tree' parameter while still always excluding artifacts
- Update tests for the ToolResponse {status,message,result} wrapper and add binary-artifact coverage
Thanks! Yes, that's correct. |
|
Hi, nice PR, just something we need from the MCP 👍 |
|
Hi. Thanks for working on this! I notice we now have some filtering for binary artifacts. One use case to consider is people running a Ultimately the use case I'm presenting is something like having an Agent/LLM via jenkins MCP say:
|
When kola tests fail, the pipeline uploads log bundle tarballs as Jenkins build artifacts. Add documentation on the artifact structure (journal.txt, console.txt, ignition.json, rerun/ directory) and what to look for when analyzing test failures. Note the current limitation that the Jenkins MCP Server Plugin does not yet support downloading build artifacts, and link to jenkinsci/mcp-server-plugin#42 as a potential future solution. Assisted-By: <anthropic/claude-opus-4.6>
When kola tests fail, the pipeline uploads log bundle tarballs as Jenkins build artifacts. Add documentation on the artifact structure (journal.txt, console.txt, ignition.json, rerun/ directory) and what to look for when analyzing test failures. Note the current limitation that the Jenkins MCP Server Plugin does not yet support downloading build artifacts, and link to jenkinsci/mcp-server-plugin#42 as a potential future solution. Assisted-By: <anthropic/claude-opus-4.6>
When kola tests fail, the pipeline uploads log bundle tarballs as Jenkins build artifacts. Add documentation on the artifact structure (journal.txt, console.txt, ignition.json, rerun/ directory) and what to look for when analyzing test failures. Note the current limitation that the Jenkins MCP Server Plugin does not yet support downloading build artifacts, and link to jenkinsci/mcp-server-plugin#42 as a potential future solution. Assisted-By: <anthropic/claude-opus-4.6>
When kola tests fail, the pipeline uploads log bundle tarballs as Jenkins build artifacts. Add documentation on the artifact structure (journal.txt, console.txt, ignition.json, rerun/ directory) and what to look for when analyzing test failures. Note the current limitation that the Jenkins MCP Server Plugin does not yet support downloading build artifacts, and link to jenkinsci/mcp-server-plugin#42 as a potential future solution. Assisted-By: <anthropic/claude-opus-4.6>
When kola tests fail, the pipeline uploads log bundle tarballs as Jenkins build artifacts. Add documentation on the artifact structure (journal.txt, console.txt, ignition.json, rerun/ directory) and what to look for when analyzing test failures. Note the current limitation that the Jenkins MCP Server Plugin does not yet support downloading build artifacts, and link to jenkinsci/mcp-server-plugin#42 as a potential future solution. Assisted-By: <anthropic/claude-opus-4.6>
This PR implements issue #32 by adding new tools for artifact management and optimizing the getBuild response size.
New Tools Added
getBuildArtifacts - Returns only the artifacts array from a build
o Takes jobFullName and optional buildNumber parameters
o Significantly reduces payload size compared to full getBuild response
o Returns empty array for jobs without artifacts or non-existent jobs
o Fixed JSON concatenation issue for top-level lists
getBuildArtifact - Provides paginated access to individual artifact file contents
o Supports offset/limit parameters for large files
o Returns artifact content as text with pagination metadata
o Includes safety limits to prevent excessive memory usage
Optimizations
o Created RunWithoutArtifactsSerializer to filter out artifacts
o Updated JenkinsExportedBeanSerializerModifier to use custom serializer
o Maintains all other build information while reducing response size
Testing done
Comprehensive test coverage
o BuildArtifactsExtensionTest - Integration tests for new tools
o GetBuildWithoutArtifactsTest - Verifies getBuild optimization
o BuildArtifactsExtensionCompileTest - Basic compilation verification
Manual test
o Augment Code MCP client w/
mvn hpi:run- Found JSON issue with top-level listo Manual test with Augment Code and production Jenkins server
Submitter checklist