office-dynamixs-ai/dynamixs-ai-mcp/src/main/java/ai/dynamixs/mcp/MCPTestEndpoint.java

254 lines
No EOL
9 KiB
Java

package ai.dynamixs.mcp;
import java.io.Serializable;
import java.util.List;
import java.util.logging.Logger;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.json.Json;
import jakarta.json.JsonArrayBuilder;
import jakarta.json.JsonObject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
/**
* Test endpoint for MCP server discovery and debugging Similar to A2A Agent
* Card but for MCP protocol
*
* @author rsoika
*/
@Named
@RequestScoped
@Path("/mcp/debug/")
@Produces({ MediaType.APPLICATION_JSON })
public class MCPTestEndpoint implements Serializable {
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(MCPTestEndpoint.class.getSimpleName());
@Context
UriInfo uriInfo;
@Inject
MCPService mcpService;
/**
* MCP Server Information Endpoint (similar to A2A Agent Card) URL:
* /mcp/server-info
*/
@GET
@Path("/server-info")
public Response getServerInfo() {
try {
JsonObject serverInfo = buildServerInfo();
return Response.ok(serverInfo).build();
} catch (Exception e) {
logger.severe("Error creating MCP server info: " + e.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(Json.createObjectBuilder()
.add("error", "Internal server error")
.add("message", e.getMessage())
.build())
.build();
}
}
/**
* Quick test endpoint to list all available resources URL: /mcp/test/resources
*/
@GET
@Path("/test/resources")
public Response testResources() {
try {
List<MCPResource> resources = mcpService.parseResources();
JsonArrayBuilder resourcesBuilder = Json.createArrayBuilder();
for (MCPResource resource : resources) {
if (resource.isValid()) {
resourcesBuilder.add(resource.toJsonObject());
}
}
JsonObject result = Json.createObjectBuilder()
.add("status", "success")
.add("count", resources.size())
.add("resources", resourcesBuilder.build())
.build();
return Response.ok(result).build();
} catch (Exception e) {
logger.severe("Error testing resources: " + e.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(Json.createObjectBuilder()
.add("error", "Failed to parse resources")
.add("message", e.getMessage())
.build())
.build();
}
}
/**
* Quick test endpoint to list all available tools URL: /mcp/test/tools
*/
@GET
@Path("/test/tools")
public Response testTools() {
try {
List<MCPTool> tools = mcpService.parseTools();
JsonArrayBuilder toolsBuilder = Json.createArrayBuilder();
for (MCPTool tool : tools) {
if (tool.isValid()) {
toolsBuilder.add(tool.toJsonObject());
}
}
JsonObject result = Json.createObjectBuilder()
.add("status", "success")
.add("count", tools.size())
.add("tools", toolsBuilder.build())
.build();
return Response.ok(result).build();
} catch (Exception e) {
logger.severe("Error testing tools: " + e.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(Json.createObjectBuilder()
.add("error", "Failed to parse tools")
.add("message", e.getMessage())
.build())
.build();
}
}
/**
* Health check endpoint URL: /mcp/health
*/
@GET
@Path("/health")
public Response healthCheck() {
try {
List<MCPResource> resources = mcpService.parseResources();
List<MCPTool> tools = mcpService.parseTools();
JsonObject health = Json.createObjectBuilder()
.add("status", "healthy")
.add("timestamp", java.time.Instant.now().toString())
.add("server", "Dynamixs.AI MCP Server")
.add("version", "1.0.0")
.add("protocol", "MCP 2024-11-05")
.add("endpoint", getBaseUrl() + "mcp/v1")
.add("resources_count", resources.size())
.add("tools_count", tools.size())
.build();
return Response.ok(health).build();
} catch (Exception e) {
logger.severe("Health check failed: " + e.getMessage());
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
.entity(Json.createObjectBuilder()
.add("status", "unhealthy")
.add("error", e.getMessage())
.build())
.build();
}
}
/**
* Builds comprehensive server information (MCP equivalent of A2A Agent Card)
*/
private JsonObject buildServerInfo() {
List<MCPResource> resources = mcpService.parseResources();
List<MCPTool> tools = mcpService.parseTools();
// Server capabilities
JsonObject capabilities = Json.createObjectBuilder()
.add("resources", Json.createObjectBuilder()
.add("subscribe", false)
.add("listChanged", false)
.build())
.add("tools", Json.createObjectBuilder().build())
.add("logging", Json.createObjectBuilder().build())
.build();
// Protocol information
JsonObject protocol = Json.createObjectBuilder()
.add("name", "Model Context Protocol")
.add("version", "2024-11-05")
.add("transport", "HTTP/JSON-RPC 2.0")
.build();
// Server metadata
JsonObject server = Json.createObjectBuilder()
.add("name", "Dynamixs.AI MCP Server")
.add("version", "1.0.0")
.add("description", "MCP server for Imixs-Workflow BPM platform")
.add("vendor", "Dynamixs.AI")
.add("platform", "Jakarta EE 10 / Imixs-Workflow")
.build();
// Endpoints
JsonObject endpoints = Json.createObjectBuilder()
.add("jsonrpc", getBaseUrl() + "mcp/v1")
.add("health", getBaseUrl() + "mcp/health")
.add("server_info", getBaseUrl() + "mcp/server-info")
.add("test_resources", getBaseUrl() + "mcp/test/resources")
.add("test_tools", getBaseUrl() + "mcp/test/tools")
.build();
// Statistics
JsonObject statistics = Json.createObjectBuilder()
.add("resources_available", resources.size())
.add("tools_available", tools.size())
.add("last_updated", java.time.Instant.now().toString())
.build();
// Resource summary
JsonArrayBuilder resourceSummary = Json.createArrayBuilder();
for (MCPResource resource : resources) {
if (resource.isValid()) {
resourceSummary.add(Json.createObjectBuilder()
.add("uri", resource.getUri())
.add("name", resource.getName())
.add("mimeType", resource.getMimeType() != null ? resource.getMimeType() : "text/plain")
.build());
}
}
// Tool summary
JsonArrayBuilder toolSummary = Json.createArrayBuilder();
for (MCPTool tool : tools) {
if (tool.isValid()) {
toolSummary.add(Json.createObjectBuilder()
.add("name", tool.getName())
.add("description", tool.getDescription())
.build());
}
}
// Build complete server info
return Json.createObjectBuilder()
.add("protocol", protocol)
.add("server", server)
.add("capabilities", capabilities)
.add("endpoints", endpoints)
.add("statistics", statistics)
.add("resource_summary", resourceSummary.build())
.add("tool_summary", toolSummary.build())
.build();
}
private String getBaseUrl() {
return uriInfo.getBaseUri().toString();
}
}