REST API Starter

The jhelm-rest module exposes Helm operations as a REST API with OpenAPI/Swagger documentation. As of 0.4.0 it is split into a pure jhelm-rest library and a jhelm-rest-starter that carries the Spring Boot auto-configuration (Spring-Boot-Admin style). Add the starter for the auto-configured experience, or depend on the library directly to wire it up yourself.

1. Getting Started

1.1. Maven Dependency

Add jhelm-rest-starter to your Spring Boot web application:


    org.alexmond
    jhelm-rest-starter
    0.6.0

For Swagger UI, add springdoc-openapi:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>3.0.2</version>
</dependency>

1.2. Sample Application

A ready-to-run sample is available in the jhelm-rest-sample module:

cd jhelm-rest-sample
../mvnw spring-boot:run

Open http://localhost:8080/swagger-ui.html to see all endpoints.

2. Configuration

Property Default Description

jhelm.security.mode

READ_ONLY

Shared access mode (also used by the MCP server). READ_ONLY disables the cluster-mutating endpoints (install/upgrade/uninstall/rollback/test, repo add/remove/push); FULL enables them — but only together with an API key (deny-by-default).

jhelm.security.api-key

(none)

API key required on mutating requests via the X-API-Key header. With no key set, mutating operations stay disabled even in FULL mode.

jhelm.rest.base-path

/api/v1

Base path prefix for all REST endpoints

jhelm.rest.temp-dir

System temp dir

Base directory for server-managed temporary files used during chart operations

jhelm:
  security:
    mode: FULL                 # READ_ONLY (default) or FULL
    api-key: change-me         # required to enable mutating endpoints
  rest:
    base-path: /api/v1
    temp-dir: /var/lib/jhelm/tmp

A mutating endpoint returns 403 when mutation is disabled (read-only, or no key), 401 on a missing/invalid key, and otherwise proceeds. See Security for the full model. The built-in key is the floor; wire Spring Security in your application for real multi-user auth.

3. Auto-Configuration

JhelmRestAutoConfiguration conditionally registers controllers based on available beans from JhelmCoreAutoConfiguration:

Controller Condition Endpoints

ReleaseController

ListAction + InstallAction + RepoManager present (requires jhelm-kube)

15 release management endpoints

ChartController

TemplateAction + RepoManager present

9 chart operation endpoints

RepoController

RepoManager present

9 repository management endpoints

HubController

SearchHubAction present

1 ArtifactHub search endpoint

DependencyController

DependencyResolver present

1 dependency management endpoint

Release endpoints require jhelm-kube on the classpath (Kubernetes client). All other endpoints work with jhelm-core alone.

4. API Reference

4.1. Releases — /api/v1/releases

Method Path Description

GET

/releases?namespace=default

List all releases in a namespace

GET

/releases/{name}?namespace=default

Get release status

POST

/releases

Install a release from a chart reference

POST

/releases/upload

Install a release from an uploaded .tgz archive (multipart)

PUT

/releases/{name}?namespace=default

Upgrade a release from a chart reference

POST

/releases/{name}/upgrade/upload?namespace=default

Upgrade a release from an uploaded .tgz archive (multipart)

DELETE

/releases/{name}?namespace=default

Uninstall a release

GET

/releases/{name}/history?namespace=default

Get release revision history

POST

/releases/{name}/rollback?namespace=default

Rollback to a previous revision

POST

/releases/{name}/test?namespace=default&timeoutSeconds=300

Run test hooks

GET

/releases/{name}/values?namespace=default&all=false

Get release values (user overrides or all merged)

GET

/releases/{name}/manifest?namespace=default

Get rendered Kubernetes manifest

GET

/releases/{name}/notes?namespace=default

Get release notes

GET

/releases/{name}/hooks?namespace=default

List Helm hooks

GET

/releases/{name}/resources?namespace=default

List resource statuses

4.1.1. Install a Release

From a chart reference:

curl -X POST http://localhost:8080/api/v1/releases \
  -H 'Content-Type: application/json' \
  -d '{
    "chartRef": "bitnami/nginx",
    "version": "18.3.1",
    "releaseName": "my-release",
    "namespace": "production",
    "values": {
      "replicaCount": 3,
      "image": {"tag": "v2.0"}
    },
    "dryRun": false
  }'

From an uploaded .tgz archive:

curl -X POST http://localhost:8080/api/v1/releases/upload \
  -F '[email protected];type=application/gzip' \
  -F 'request={"releaseName": "my-release", "namespace": "production"};type=application/json'

4.1.2. Upgrade a Release

From a chart reference:

curl -X PUT http://localhost:8080/api/v1/releases/my-release?namespace=production \
  -H 'Content-Type: application/json' \
  -d '{
    "chartRef": "bitnami/nginx",
    "version": "19.0.0",
    "values": {"image": {"tag": "v2.1"}},
    "dryRun": false
  }'

From an uploaded .tgz archive:

curl -X POST http://localhost:8080/api/v1/releases/my-release/upgrade/upload?namespace=production \
  -F '[email protected];type=application/gzip' \
  -F 'request={"values": {"image": {"tag": "v2.1"}}};type=application/json'

4.1.3. Rollback a Release

curl -X POST http://localhost:8080/api/v1/releases/my-release/rollback?namespace=production \
  -H 'Content-Type: application/json' \
  -d '{"revision": 2}'

4.2. Charts — /api/v1/charts

Method Path Description

POST

/charts/template

Render chart templates from a chart reference

POST

/charts/template/upload

Render chart templates from an uploaded .tgz archive (multipart)

POST

/charts/create

Scaffold a new chart and return as .tgz download

GET

/charts/show?chartRef=…​&version=…​

Show all chart info (metadata, values, README)

GET

/charts/show/values?chartRef=…​&version=…​

Show default values.yaml

GET

/charts/show/readme?chartRef=…​&version=…​

Show chart README

GET

/charts/show/chart?chartRef=…​&version=…​

Show Chart.yaml metadata

GET

/charts/show/crds?chartRef=…​&version=…​

Show Custom Resource Definitions

4.2.1. Render Templates

From a chart reference:

curl -X POST http://localhost:8080/api/v1/charts/template \
  -H 'Content-Type: application/json' \
  -d '{
    "chartRef": "bitnami/nginx",
    "version": "18.3.1",
    "releaseName": "my-release",
    "namespace": "production",
    "values": {"replicaCount": 3}
  }'

From an uploaded .tgz archive:

curl -X POST http://localhost:8080/api/v1/charts/template/upload \
  -F '[email protected];type=application/gzip' \
  -F 'request={"releaseName": "my-release", "namespace": "production"};type=application/json'

4.2.2. Create a Chart

curl -X POST http://localhost:8080/api/v1/charts/create \
  -H 'Content-Type: application/json' \
  -o my-chart.tgz \
  -d '{"name": "my-chart"}'

Response: binary .tgz download with Content-Type: application/gzip.

4.3. Repositories — /api/v1/repos

Method Path Description

POST

/repos

Add a chart repository

GET

/repos

List all configured repositories

DELETE

/repos/{name}

Remove a repository

POST

/repos/{name}/update

Update repository index

GET

/repos/{name}/charts

List all charts in a repository

GET

/repos/{name}/charts/{chart}/versions

List available chart versions

POST

/repos/pull

Pull a chart (repo or OCI) and return as .tgz download

POST

/repos/update-all

Update all repository indices

POST

/repos/push

Push an uploaded .tgz chart to a remote registry (multipart)

4.3.1. Add a Repository

curl -X POST http://localhost:8080/api/v1/repos \
  -H 'Content-Type: application/json' \
  -d '{"name": "bitnami", "url": "https://charts.bitnami.com/bitnami"}'

4.3.2. List Charts in a Repository

curl http://localhost:8080/api/v1/repos/bitnami/charts

Response:

[
  {"name": "bitnami/nginx", "chartVersion": "18.3.1", "appVersion": "1.27.3", "description": "..."},
  {"name": "bitnami/redis", "chartVersion": "20.0.0", "appVersion": "7.4.1", "description": "..."}
]

4.3.3. List Chart Versions

curl http://localhost:8080/api/v1/repos/bitnami/charts/nginx/versions

Response:

[
  {"name": "nginx", "chartVersion": "18.3.1", "appVersion": "1.27.3", "description": "..."},
  {"name": "nginx", "chartVersion": "18.3.0", "appVersion": "1.27.3", "description": "..."}
]

4.3.4. Pull a Chart

Pulls from a repository or OCI registry. The endpoint auto-detects OCI URLs by the oci:// prefix.

From a repository:

curl -X POST http://localhost:8080/api/v1/repos/pull \
  -H 'Content-Type: application/json' \
  -o nginx-18.3.1.tgz \
  -d '{"chart": "bitnami/nginx", "version": "18.3.1"}'

From an OCI registry:

curl -X POST http://localhost:8080/api/v1/repos/pull \
  -H 'Content-Type: application/json' \
  -o nginx-1.0.0.tgz \
  -d '{"chart": "oci://registry.example.com/charts/nginx:1.0.0"}'

Response: binary .tgz download with Content-Type: application/gzip.

4.3.5. Update All Repositories

curl -X POST http://localhost:8080/api/v1/repos/update-all

4.3.6. Push a Chart

curl -X POST http://localhost:8080/api/v1/repos/push \
  -F '[email protected];type=application/gzip' \
  -F 'remote=oci://registry.example.com/charts/nginx'

4.4. Hub — /api/v1/hub

Method Path Description

GET

/hub/search?keyword=…​&maxResults=20

Search ArtifactHub for Helm charts

4.4.1. Search ArtifactHub

curl 'http://localhost:8080/api/v1/hub/search?keyword=nginx&maxResults=5'

Response:

[
  {
    "name": "nginx",
    "version": "18.3.1",
    "appVersion": "1.27.3",
    "repoName": "bitnami",
    "repoUrl": "https://charts.bitnami.com/bitnami",
    "description": "NGINX Open Source is a web server..."
  }
]
ArtifactHub API limits maxResults to 60 per request.

4.5. Dependencies — /api/v1/dependencies

Method Path Description

POST

/dependencies/resolve

Resolve dependency versions from a chart reference and return Chart.lock YAML

4.5.1. Resolve Dependencies

curl -X POST http://localhost:8080/api/v1/dependencies/resolve \
  -H 'Content-Type: application/json' \
  -d '{"chartRef": "bitnami/nginx", "version": "18.3.1"}'

Response: YAML content with Content-Type: text/yaml:

dependencies:
- name: redis
  version: "18.0.0"
  repository: "https://charts.bitnami.com/bitnami"
digest: "sha256:..."
generated: "2026-03-08T..."

5. Error Handling

All endpoints return consistent error responses via JhelmRestExceptionHandler:

  • 400 Bad Request — Missing required fields or invalid arguments

  • 404 Not Found — Release or resource not found

Error response format:

{"message": "chartRef is required"}

6. Spring Boot Integration

6.1. Minimal Application

@SpringBootApplication
public class MyHelmApp {
    public static void main(String[] args) {
        SpringApplication.run(MyHelmApp.class, args);
    }
}

With jhelm-rest on the classpath, all endpoints are auto-configured. No additional code is needed.

6.2. Custom Base Path

jhelm:
  rest:
    base-path: /helm/api

All endpoints will be available under /helm/api/releases, /helm/api/charts, etc.

6.3. Overriding Controllers

All controllers are registered with @ConditionalOnMissingBean. Define your own to replace:

@RestController
@RequestMapping("/api/v1/releases")
public class CustomReleaseController {
    // Your custom implementation
}

7. MCP Server

In addition to the REST API, jhelm ships an Model Context Protocol (MCP) server that exposes the same operation set as tools an AI agent can call. It is built on Spring AI and mirrors the REST surface (releases, charts, repositories, dependencies, hub search).

Add jhelm-mcp-starter to a Spring Boot application for the auto-configured server:


    org.alexmond
    jhelm-mcp-starter
    0.6.0

The MCP server shares the same jhelm.security.* gate as the REST API. It defaults to READ_ONLY, so only the non-mutating tools are registered; the mutating tools appear only in FULL mode with an API key set (deny-by-default):

jhelm:
  security:
    mode: READ_ONLY   # READ_ONLY (default) or FULL
    api-key: change-me

When an API key is set, the MCP HTTP endpoints (/mcp, /sse) require it; a locally launched server over stdio is not forced to present one. See MCP Server and Security.