Conversation
denislavprinov
commented
Jan 15, 2026
- Introduces a new Model Context Protocol (MCP) server module (hawkbit-mcp) that enables AI assistants to interact with hawkBit
- Provides MCP tools for managing all hawkBit entities: Targets, Distribution Sets, Software Modules, Rollouts, Actions, and Target Filters
- Includes MCP resources for hawkBit documentation
- Exposes predefined prompts
- Supports credential pass-through authentication to hawkBit REST API
dc059b7 to
b0d48e0
Compare
hawkbit-monolith/hawkbit-update-server/src/main/resources/application.properties
Outdated
Show resolved
Hide resolved
hawkbit-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/HawkbitMcpServerApplication.java
Show resolved
Hide resolved
...-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/client/HawkBitAuthenticationValidator.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Denislav Prinov <[email protected]>
f1f3e2d to
1607ecf
Compare
…er build Signed-off-by: Denislav Prinov <[email protected]>
1607ecf to
5946a09
Compare
...-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/client/HawkbitAuthenticationValidator.java
Outdated
Show resolved
Hide resolved
hawkbit-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/config/HawkbitClientConfiguration.java
Show resolved
Hide resolved
hawkbit-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/config/HawkbitMcpProperties.java
Show resolved
Hide resolved
hawkbit-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/dto/ManageActionRequest.java
Outdated
Show resolved
Hide resolved
hawkbit-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/dto/ManageDistributionSetRequest.java
Outdated
Show resolved
Hide resolved
hawkbit-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/dto/ManageRolloutRequest.java
Outdated
Show resolved
Hide resolved
hawkbit-mcp/src/main/java/org/eclipse/hawkbit/mcp/server/dto/ManageSoftwareModuleRequest.java
Outdated
Show resolved
Hide resolved
… authentication validator conditional, and separate HTTP/STDIO client configurations Signed-off-by: Denislav Prinov <[email protected]>
| public static final String AUTH_HEADER_ATTRIBUTE = "hawkbit.mcp.auth.header"; | ||
|
|
||
| private final HawkbitAuthenticationValidator authenticationValidator; | ||
| private final AuthenticationValidator authenticationValidator; |
There was a problem hiding this comment.
Why do you need a dummy validator when validation is disabled? Consider making it Optional and just skip the http.addFilterBefore(...);
| log.debug("Managing target: operation={}, controllerId={}", request.operation(), request.controllerId()); | ||
| "DELETE (remove target by controllerId). " + | ||
| "Use 'type' field to select operation: " + | ||
| "{\"type\":\"Create\",\"body\":{\"controllerId\":\"id\",\"name\":\"name\"}}, " + |
There was a problem hiding this comment.
Add Note: When creating a target without a specific target type, set \"targetType\": null. to set target type as null if not specified explicitly.
| log.debug("Managing rollout: operation={}, rolloutId={}", request.operation(), request.rolloutId()); | ||
| "Use 'type' field to select operation. " + | ||
| "Types: Create, Update, Delete, Start, Pause, Stop, Resume, Approve, Deny, Retry, TriggerNextGroup. " + | ||
| "Examples: {\"type\":\"Create\",\"body\":{...}}, " + |
There was a problem hiding this comment.
It is a good idea to add the knowledge that
- for the rollout type, enum names ("soft", "forced", "timeforced", "downloadonly") should be used, not constants ("SOFT", "FORCED", etc.).
- if
groupsproperty is specified, theamountGroupsshould be skipped
| * | ||
| * @param actionIds list containing the single action ID to delete (use single-element list) | ||
| */ | ||
| record Delete(List<Long> actionIds) implements ActionRequest {} |
There was a problem hiding this comment.
Use Long actionId for this request
| public HawkbitClient hawkbitClient(final HawkbitServer server, | ||
| final Encoder encoder, | ||
| final Decoder decoder, | ||
| final Contract contract) { | ||
| log.info("Configuring hawkBit client for HTTP mode (per-request authentication)"); | ||
| return HawkbitClient.builder() | ||
| .hawkBitServer(server) | ||
| .encoder(encoder) | ||
| .decoder(decoder) | ||
| .contract(contract) | ||
| .requestInterceptorFn(httpRequestInterceptor()) | ||
| .build(); | ||
| } |
There was a problem hiding this comment.
Consider moving this method to the HawkbitClientConfiguration, providing only the requestInterceptorFn in the dedicated config.
There was a problem hiding this comment.
tenant\\username is not supported in hawkbit
There was a problem hiding this comment.
Do you think it is better to annotate the respective properties in HawkbitMcpProperties with
@Value("${HAWKBIT_USERNAME:#{null}}")@Value("${HAWKBIT_PASSWORD:#{null}}")
and have it null when not set?
This will allow setting an empty string as a valid value?
| log.info("Configured tenant with static credentials for STDIO mode"); | ||
| } else { | ||
| tenant.setUsername(null); | ||
| tenant.setPassword(null); |
There was a problem hiding this comment.
Consider this comment and if the suggested approach is used, there will be no need to check if credentials are set.
Signed-off-by: Denislav Prinov <[email protected]>
|


