This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-mcp-server.git
commit 200082a05a9723bfcaa579066c25623f8b6efd78 Author: Robert Munteanu <[email protected]> AuthorDate: Wed Dec 10 17:51:53 2025 +0100 feat(mcp-server): clearly mark fragment bundles --- pom.xml | 5 +++++ .../impl/contribs/BundleResourceContribution.java | 22 ++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index e41f259..722343a 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,11 @@ <artifactId>org.osgi.framework</artifactId> <scope>provided</scope> </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.resource</artifactId> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.annotation.bundle</artifactId> diff --git a/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleResourceContribution.java b/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleResourceContribution.java index fc7ac2a..833264c 100644 --- a/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleResourceContribution.java +++ b/src/main/java/org/apache/sling/mcp/server/impl/contribs/BundleResourceContribution.java @@ -37,12 +37,14 @@ import io.modelcontextprotocol.spec.McpSchema.TextResourceContents; import org.apache.sling.mcp.server.impl.McpServerContribution; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; +import org.osgi.framework.wiring.BundleRevision; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @Component public class BundleResourceContribution implements McpServerContribution { + private static final String URI_BUNDLES_ALL = "bundles://all"; private static final String RESOURCE_TEMPLATE_BUNDLES_STATE_PREFIX = "bundles://state/"; private static final String RESOURCE_TEMPLATE_BUNDLES_STATE_PATTERN = RESOURCE_TEMPLATE_BUNDLES_STATE_PREFIX + "{state}"; @@ -59,16 +61,17 @@ public class BundleResourceContribution implements McpServerContribution { return Optional.of(new McpStatelessServerFeatures.SyncResourceSpecification( new Resource.Builder() - .name("bundle") - .uri("bundle://") - .description("OSGi bundle status") + .name("bundles") + .uri(URI_BUNDLES_ALL) + .description( + "List all OSGi bundles with symbolic name, version, and state. Fragment bundles are marked with [Fragment]") .mimeType("text/plain") .build(), (context, request) -> { String bundleInfo = Stream.of(ctx.getBundles()).map(this::describe).collect(Collectors.joining("\n")); - TextResourceContents contents = new TextResourceContents("bundle://", "text/plain", bundleInfo); + TextResourceContents contents = new TextResourceContents(URI_BUNDLES_ALL, "text/plain", bundleInfo); return new McpSchema.ReadResourceResult(List.of(contents)); })); @@ -88,9 +91,7 @@ public class BundleResourceContribution implements McpServerContribution { if (!bundleState.isValid()) { throw new IllegalArgumentException("Invalid bundle state: " + requestedState); } - String bundleInfo = ""; - // extract desired state from URI - bundleInfo = Arrays.stream(ctx.getBundles()) + String bundleInfo = Arrays.stream(ctx.getBundles()) .filter(b -> b.getState() == bundleState.getState()) .map(this::describe) .collect(Collectors.joining("\n")); @@ -130,7 +131,12 @@ public class BundleResourceContribution implements McpServerContribution { } private String describe(Bundle b) { - return "Bundle " + b.getSymbolicName() + " (version " + b.getVersion() + ") is in state " + boolean isFragment = Optional.ofNullable(b.adapt(BundleRevision.class)).stream() + .map(br -> (br.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) + .findAny() + .orElse(false); + String additionalInfo = isFragment ? " [Fragment]" : ""; + return "Bundle " + b.getSymbolicName() + additionalInfo + " (version " + b.getVersion() + ") is in state " + BundleState.fromState(b.getState()) + " (" + b.getState() + ")"; } }
