Skip to content

Commit f589f4d

Browse files
authored
Add cache control hints to resource templates with configuration (#237)
Signed-off-by: David Kornel <kornys@outlook.com>
1 parent 5848bd3 commit f589f4d

9 files changed

Lines changed: 42 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- **Dev environment manifests and scripts** for deploying Elasticsearch with Fluent Bit on Kind clusters and ECK Operator on OpenShift with automated API key provisioning, ClusterLogForwarder integration, and passthrough TLS routes
1515
- **System tests** for Elasticsearch log provider covering log collection, field mapping, time window queries, and error handling
1616
- **Thanos and VictoriaMetrics compatibility documentation** — the existing Prometheus metrics provider works with Thanos Querier and VictoriaMetrics without code changes
17+
- **Resource template cache control** — All 6 resource templates now include cache control hints with a 30-second TTL and PUBLIC scope, allowing MCP clients to cache Kubernetes resource state and reduce redundant API calls. TTL is configurable via `mcp.resource-template.cache-ttl-seconds` (default: 30).
1718

1819
### Changed
1920

docs/strimzi-mcp/configuration.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,20 @@ Completion results (namespace lists, cluster names, etc.) are cached to improve
655655
MCP_COMPLETION_CACHE_TTL_SECONDS=10
656656
```
657657

658+
### Resource template cache configuration
659+
660+
Control cache freshness hints for resource template responses (cluster status, topology, node pool status, topic status, user status, operator status).
661+
662+
| Property | Default | Description |
663+
|----------|---------|-------------|
664+
| `mcp.resource-template.cache-ttl-seconds` | `30` | Cache TTL for resource template responses in seconds |
665+
666+
Resource templates return Kubernetes resource state. A 30-second TTL lets MCP clients cache responses while keeping data reasonably fresh.
667+
668+
```bash
669+
MCP_RESOURCE_TEMPLATE_CACHE_TTL_SECONDS=60
670+
```
671+
658672
### Topic pagination configuration
659673

660674
Control default pagination for topic listing.

strimzi-mcp/src/main/java/io/streamshub/mcp/strimzi/resource/template/KafkaClusterStatusResource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import com.fasterxml.jackson.core.JsonProcessingException;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import io.quarkiverse.mcp.server.CacheScope;
10+
import io.quarkiverse.mcp.server.Resource;
911
import io.quarkiverse.mcp.server.ResourceResponse;
1012
import io.quarkiverse.mcp.server.ResourceTemplate;
1113
import io.quarkiverse.mcp.server.ResourceTemplateArg;
@@ -46,7 +48,8 @@ public class KafkaClusterStatusResource {
4648
uriTemplate = StrimziConstants.ResourceUris.KAFKA_STATUS,
4749
description = "Current status and conditions of a Kafka cluster"
4850
+ " including readiness, version, listeners, and replica counts.",
49-
mimeType = "application/json"
51+
mimeType = "application/json",
52+
cacheControl = @Resource.CacheControl(ttlMs = 30000, cacheScope = CacheScope.PUBLIC)
5053
)
5154
public ResourceResponse getClusterStatus(
5255
@ResourceTemplateArg(name = "namespace") final String namespace,

strimzi-mcp/src/main/java/io/streamshub/mcp/strimzi/resource/template/KafkaClusterTopologyResource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import com.fasterxml.jackson.core.JsonProcessingException;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import io.quarkiverse.mcp.server.CacheScope;
10+
import io.quarkiverse.mcp.server.Resource;
911
import io.quarkiverse.mcp.server.ResourceResponse;
1012
import io.quarkiverse.mcp.server.ResourceTemplate;
1113
import io.quarkiverse.mcp.server.ResourceTemplateArg;
@@ -48,7 +50,8 @@ public class KafkaClusterTopologyResource {
4850
uriTemplate = StrimziConstants.ResourceUris.KAFKA_TOPOLOGY,
4951
description = "Cluster topology: node pools, roles,"
5052
+ " replica counts, and storage configuration.",
51-
mimeType = "application/json"
53+
mimeType = "application/json",
54+
cacheControl = @Resource.CacheControl(ttlMs = 30000, cacheScope = CacheScope.PUBLIC)
5255
)
5356
public ResourceResponse getClusterTopology(
5457
@ResourceTemplateArg(name = "namespace") final String namespace,

strimzi-mcp/src/main/java/io/streamshub/mcp/strimzi/resource/template/KafkaNodePoolStatusResource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import com.fasterxml.jackson.core.JsonProcessingException;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import io.quarkiverse.mcp.server.CacheScope;
10+
import io.quarkiverse.mcp.server.Resource;
911
import io.quarkiverse.mcp.server.ResourceResponse;
1012
import io.quarkiverse.mcp.server.ResourceTemplate;
1113
import io.quarkiverse.mcp.server.ResourceTemplateArg;
@@ -46,7 +48,8 @@ public class KafkaNodePoolStatusResource {
4648
uriTemplate = StrimziConstants.ResourceUris.NODEPOOL_STATUS,
4749
description = "KafkaNodePool status, ready replicas, roles,"
4850
+ " and storage configuration.",
49-
mimeType = "application/json"
51+
mimeType = "application/json",
52+
cacheControl = @Resource.CacheControl(ttlMs = 30000, cacheScope = CacheScope.PUBLIC)
5053
)
5154
public ResourceResponse getNodePoolStatus(
5255
@ResourceTemplateArg(name = "namespace") final String namespace,

strimzi-mcp/src/main/java/io/streamshub/mcp/strimzi/resource/template/KafkaTopicStatusResource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import com.fasterxml.jackson.core.JsonProcessingException;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import io.quarkiverse.mcp.server.CacheScope;
10+
import io.quarkiverse.mcp.server.Resource;
911
import io.quarkiverse.mcp.server.ResourceResponse;
1012
import io.quarkiverse.mcp.server.ResourceTemplate;
1113
import io.quarkiverse.mcp.server.ResourceTemplateArg;
@@ -46,7 +48,8 @@ public class KafkaTopicStatusResource {
4648
uriTemplate = StrimziConstants.ResourceUris.TOPIC_STATUS,
4749
description = "KafkaTopic status, conditions, and topic"
4850
+ " configuration including partitions and replicas.",
49-
mimeType = "application/json"
51+
mimeType = "application/json",
52+
cacheControl = @Resource.CacheControl(ttlMs = 30000, cacheScope = CacheScope.PUBLIC)
5053
)
5154
public ResourceResponse getTopicStatus(
5255
@ResourceTemplateArg(name = "namespace") final String namespace,

strimzi-mcp/src/main/java/io/streamshub/mcp/strimzi/resource/template/KafkaUserStatusResource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import com.fasterxml.jackson.core.JsonProcessingException;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import io.quarkiverse.mcp.server.CacheScope;
10+
import io.quarkiverse.mcp.server.Resource;
911
import io.quarkiverse.mcp.server.ResourceResponse;
1012
import io.quarkiverse.mcp.server.ResourceTemplate;
1113
import io.quarkiverse.mcp.server.ResourceTemplateArg;
@@ -47,7 +49,8 @@ public class KafkaUserStatusResource {
4749
uriTemplate = StrimziConstants.ResourceUris.USER_STATUS,
4850
description = "KafkaUser authentication, ACL rules, quotas,"
4951
+ " and readiness status. Never includes credential secrets.",
50-
mimeType = "application/json"
52+
mimeType = "application/json",
53+
cacheControl = @Resource.CacheControl(ttlMs = 30000, cacheScope = CacheScope.PUBLIC)
5154
)
5255
public ResourceResponse getUserStatus(
5356
@ResourceTemplateArg(name = "namespace") final String namespace,

strimzi-mcp/src/main/java/io/streamshub/mcp/strimzi/resource/template/StrimziOperatorStatusResource.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import com.fasterxml.jackson.core.JsonProcessingException;
88
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import io.quarkiverse.mcp.server.CacheScope;
10+
import io.quarkiverse.mcp.server.Resource;
911
import io.quarkiverse.mcp.server.ResourceResponse;
1012
import io.quarkiverse.mcp.server.ResourceTemplate;
1113
import io.quarkiverse.mcp.server.ResourceTemplateArg;
@@ -46,7 +48,8 @@ public class StrimziOperatorStatusResource {
4648
uriTemplate = StrimziConstants.ResourceUris.OPERATOR_STATUS,
4749
description = "Strimzi operator deployment status,"
4850
+ " version, readiness, and uptime.",
49-
mimeType = "application/json"
51+
mimeType = "application/json",
52+
cacheControl = @Resource.CacheControl(ttlMs = 30000, cacheScope = CacheScope.PUBLIC)
5053
)
5154
public ResourceResponse getOperatorStatus(
5255
@ResourceTemplateArg(name = "namespace") final String namespace,

strimzi-mcp/src/main/resources/application.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ mcp.metrics.prometheus.sa-token-path=/var/run/secrets/kubernetes.io/serviceaccou
137137
# mcp.events.max-related-resources=50
138138
# Completion cache TTL in seconds (default: 5)
139139
# mcp.completion.cache-ttl-seconds=5
140+
# Resource template cache TTL in seconds (default: 30)
141+
# Controls cache freshness hints for resource template responses (cluster status, topology, etc.)
142+
# mcp.resource-template.cache-ttl-seconds=30
140143
# Default page size for list_kafka_topics (default: 100)
141144
# mcp.topics.default-page-size=100
142145

0 commit comments

Comments
 (0)