Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docker/build/build_dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ if [ -z "$1" ]; then
build "hawkbit-update-server"
# db init
build "hawkbit-repository-jpa-init"
# mcp server
build "hawkbit-mcp-server"
else
echo "Build $1"
build $1
Expand Down
109 changes: 109 additions & 0 deletions hawkbit-mcp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# hawkBit MCP Server

A standalone [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that provides AI assistants with tools to interact with [Eclipse hawkBit](https://www.eclipse.org/hawkbit/) for IoT device software update management.

## Building

From the project root directory:

```bash
mvn clean package -pl hawkbit-mcp -am -DskipTests
```

The JAR will be created at: `hawkbit-mcp/target/hawkbit-mcp-server-0-SNAPSHOT.jar`

## Configuration

The MCP server supports two transport modes:

| Mode | Use Case | Authentication |
|------|----------|----------------|
| **HTTP/SSE** | Remote access, multi-user | Per-request via `Authorization` header |
| **STDIO** | Local CLI tools (e.g., Claude Code) | Environment variables |


### HTTP Transport

Use HTTP transport when running the server as a standalone service:

```json
{
"mcpServers": {
"hawkbit-mcp": {
"type": "http",
"url": "http://localhost:8081/mcp",
"headers": {
"Authorization": "Basic <BASE64_ENCODED_CREDENTIALS>"
}
}
}
}
```

Start the server separately:

```bash
java -jar hawkbit-mcp-server-0-SNAPSHOT.jar \
--hawkbit.mcp.mgmt-url=<HAWKBIT_URL>
```

**Generating Base64 credentials:**

```bash
# Linux/Mac
echo -n "<TENANT>\\<USERNAME>:<PASSWORD>" | base64

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<TENANT>\\<USERNAME> does not work in hawkbit. Authentication should be only with <USERNAME> only.


# PowerShell
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("<TENANT>\<USERNAME>:<PASSWORD>"))
```

### STDIO Transport

Use STDIO transport for direct integration:

```json
{
"mcpServers": {
"hawkbit-mcp": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-Dspring.main.web-application-type=none",
"-jar",
"/path/to/hawkbit-mcp-server-0-SNAPSHOT.jar"
],
"env": {
"HAWKBIT_URL": "<HAWKBIT_URL>",
"HAWKBIT_USERNAME": "<TENANT>\\<USERNAME>",
"HAWKBIT_PASSWORD": "<PASSWORD>"
}
}
}
}
```

## Configuration Properties

| Property | Environment Variable | Description | Default |
|----------|---------------------|-------------|---------|
| `hawkbit.mcp.mgmt-url` | `HAWKBIT_URL` | hawkBit Management API URL | `http://localhost:8080` |
| `hawkbit.mcp.username` | `HAWKBIT_USERNAME` | Username for STDIO mode | - |
| `hawkbit.mcp.password` | `HAWKBIT_PASSWORD` | Password for STDIO mode | - |
| `hawkbit.mcp.validation.enabled` | - | Validate credentials against hawkBit | `true` |
| `hawkbit.mcp.validation.cache-ttl` | - | Cache TTL for auth validation | `600s` |

### Operation Controls

You can enable/disable specific operations globally or per-entity:

```properties
# Global: disable all deletes
hawkbit.mcp.operations.delete-enabled=false

# Per-entity: allow delete for targets only
hawkbit.mcp.operations.targets.delete-enabled=true

# Disable rollout lifecycle operations
hawkbit.mcp.operations.rollouts.start-enabled=false
hawkbit.mcp.operations.rollouts.approve-enabled=false
```
130 changes: 130 additions & 0 deletions hawkbit-mcp/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<!--

Copyright (c) 2025 Contributors to the Eclipse Foundation

This program and the accompanying materials are made
available under the terms of the Eclipse Public License 2.0
which is available at https://www.eclipse.org/legal/epl-2.0/

SPDX-License-Identifier: EPL-2.0

-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-parent</artifactId>
<version>${revision}</version>
</parent>

<artifactId>hawkbit-mcp-server</artifactId>
<name>hawkBit :: MCP Server (Standalone)</name>
<description>Standalone MCP server that connects to hawkBit via REST API</description>

<dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-sdk-mgmt</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-annotations</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-hawkbit-docs</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}/hawkbit-docs</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/../docs</directory>
<includes>
<include>README.md</include>
<include>what-is-hawkbit.md</include>
<include>quick-start.md</include>
<include>features.md</include>
<include>architecture.md</include>
<include>base-setup.md</include>
<include>hawkbit-sdk.md</include>
<include>feign-client.md</include>
<include>clustering.md</include>
<include>authentication.md</include>
<include>authorization.md</include>
<include>datamodel.md</include>
<include>rollout-management.md</include>
<include>targetstate.md</include>
<include>management-api.md</include>
<include>direct-device-integration-api.md</include>
<include>device-management-federation-api.md</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>org.eclipse.hawkbit.mcp.server.HawkbitMcpServerApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2026 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.mcp.server;

import org.eclipse.hawkbit.mcp.server.config.HawkbitMcpProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;

/**
* Standalone MCP Server application that connects to hawkBit via REST API.
* <p>
* This server acts as a proxy between MCP clients and hawkBit,
* passing through authentication credentials to the hawkBit REST API.
* </p>
*/
@SpringBootApplication(exclude = UserDetailsServiceAutoConfiguration.class)
@EnableConfigurationProperties(HawkbitMcpProperties.class)
public class HawkbitMcpServerApplication {

public static void main(String[] args) {
SpringApplication.run(HawkbitMcpServerApplication.class, args);
}
}
Loading