forked from kimhyungsik/ax_hub_mcp_tool
use bundleId to dynamically match module-wide tool manifest requests
All checks were successful
Deploy Tools / deploy (push) Successful in 7m42s
All checks were successful
Deploy Tools / deploy (push) Successful in 7m42s
This commit is contained in:
@@ -43,12 +43,17 @@ public class ToolManifestService {
|
||||
}
|
||||
|
||||
public ToolManifestResponse currentManifest() {
|
||||
return currentManifest(null);
|
||||
}
|
||||
|
||||
public ToolManifestResponse currentManifest(String categoryKey) {
|
||||
String bundleId = properties.getManifest() == null ? null : properties.getManifest().getBundleId();
|
||||
if (bundleId == null || bundleId.isBlank()) {
|
||||
throw new IllegalStateException("mcp.manifest.bundle-id must be configured");
|
||||
}
|
||||
|
||||
List<ToolManifestItem> tools = toolSupplier.get().stream()
|
||||
.filter(tool -> isMatchCategory(categoryKey, tool.getCategoryKey(), bundleId))
|
||||
.map(this::toManifestItem)
|
||||
.sorted(Comparator.comparing(ToolManifestItem::name))
|
||||
.toList();
|
||||
@@ -56,6 +61,24 @@ public class ToolManifestService {
|
||||
return new ToolManifestResponse(bundleId, revision(bundleId, tools), tools);
|
||||
}
|
||||
|
||||
private boolean isMatchCategory(String requestedCategory, String toolCategory, String bundleId) {
|
||||
if (requestedCategory == null) {
|
||||
return true;
|
||||
}
|
||||
if (requestedCategory.equalsIgnoreCase(toolCategory)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return all tools in this module if the requested category matches the module's bundle ID
|
||||
if (bundleId != null &&
|
||||
(bundleId.equalsIgnoreCase(requestedCategory) ||
|
||||
bundleId.equalsIgnoreCase("was-" + requestedCategory))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private ToolManifestItem toManifestItem(ToolMetadata tool) {
|
||||
String title = tool.getDisplayName() == null || tool.getDisplayName().isBlank()
|
||||
? tool.getName() : tool.getDisplayName();
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
/** Read-only Tool Service manifest endpoint for MCP background discovery. */
|
||||
@RestController
|
||||
@@ -22,7 +23,17 @@ public class ToolManifestController {
|
||||
@GetMapping(value = "/tool-manifest", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<ToolManifestResponse> getManifest(
|
||||
@RequestHeader(value = HttpHeaders.IF_NONE_MATCH, required = false) String ifNoneMatch) {
|
||||
ToolManifestResponse manifest = toolManifestService.currentManifest();
|
||||
return handleManifest(toolManifestService.currentManifest(), ifNoneMatch);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/tool-manifest/{categoryKey}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<ToolManifestResponse> getManifestByCategory(
|
||||
@PathVariable("categoryKey") String categoryKey,
|
||||
@RequestHeader(value = HttpHeaders.IF_NONE_MATCH, required = false) String ifNoneMatch) {
|
||||
return handleManifest(toolManifestService.currentManifest(categoryKey), ifNoneMatch);
|
||||
}
|
||||
|
||||
private ResponseEntity<ToolManifestResponse> handleManifest(ToolManifestResponse manifest, String ifNoneMatch) {
|
||||
String eTag = '"' + manifest.revision() + '"';
|
||||
if (eTag.equals(ifNoneMatch)) {
|
||||
return ResponseEntity.status(304).eTag(eTag).build();
|
||||
|
||||
Reference in New Issue
Block a user