McpService.java
package fr.tiogars.chat.domains.mcp.services;
import fr.tiogars.chat.domains.mcp.models.McpActionRequest;
import fr.tiogars.chat.domains.mcp.models.McpActionResponse;
import fr.tiogars.chat.domains.mcp.models.McpResource;
import fr.tiogars.chat.domains.mcp.models.McpServiceConfig;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Service for managing MCP services and executing actions.
*/
@Service
public class McpService {
private final Map<String, McpServiceConfig> serviceConfigs = new ConcurrentHashMap<>();
public McpService() {
// Initialize with some default MCP services
registerDefaultServices();
}
private void registerDefaultServices() {
// Filesystem MCP server
McpServiceConfig filesystemConfig = new McpServiceConfig(
"filesystem",
"File System Access",
"Access to local file system operations",
"npx @modelcontextprotocol/server-filesystem",
Map.of(),
true,
30
);
serviceConfigs.put(filesystemConfig.id(), filesystemConfig);
// Process MCP server
McpServiceConfig processConfig = new McpServiceConfig(
"process",
"Process Management",
"Execute system processes and commands",
"npx @modelcontextprotocol/server-process",
Map.of(),
true,
30
);
serviceConfigs.put(processConfig.id(), processConfig);
// HTTP MCP server
McpServiceConfig httpConfig = new McpServiceConfig(
"http",
"HTTP Requests",
"Make HTTP requests to external services",
"npx @modelcontextprotocol/server-http",
Map.of(),
true,
60
);
serviceConfigs.put(httpConfig.id(), httpConfig);
}
/**
* Get all registered MCP service configurations.
*
* @return list of all MCP service configs
*/
public List<McpServiceConfig> getAllServices() {
return serviceConfigs.values().stream().toList();
}
/**
* Get a specific MCP service configuration by ID.
*
* @param serviceId the service ID
* @return the service configuration or null if not found
*/
public McpServiceConfig getService(String serviceId) {
return serviceConfigs.get(serviceId);
}
/**
* Register a new MCP service.
*
* @param config the service configuration
* @return the registered configuration
*/
public McpServiceConfig registerService(McpServiceConfig config) {
serviceConfigs.put(config.id(), config);
return config;
}
/**
* Execute an action on an MCP service.
* This is a simplified implementation that simulates MCP calls.
* In a real implementation, this would connect to the actual MCP server.
*
* @param request the action request
* @return the action response
*/
public McpActionResponse executeAction(McpActionRequest request) {
Instant start = Instant.now();
McpServiceConfig config = serviceConfigs.get(request.serviceId());
if (config == null || !config.enabled()) {
Instant end = Instant.now();
return new McpActionResponse(
false,
Map.of(),
List.of(),
"Service not found or disabled: " + request.serviceId(),
Duration.between(start, end).toMillis()
);
}
// Simulate action execution based on service type
McpActionResponse response = switch (request.serviceId()) {
case "filesystem" -> executeFilesystemAction(request);
case "process" -> executeProcessAction(request);
case "http" -> executeHttpAction(request);
default -> executeGenericAction(request, config);
};
Instant end = Instant.now();
return new McpActionResponse(
response.success(),
response.data(),
response.resources(),
response.error(),
Duration.between(start, end).toMillis()
);
}
private McpActionResponse executeFilesystemAction(McpActionRequest request) {
String action = request.action();
Map<String, Object> params = request.parameters() != null ? request.parameters() : Map.of();
if ("list_resources".equals(action)) {
String path = (String) params.getOrDefault("path", ".");
// Simulate listing files
McpResource resource1 = new McpResource(
"file://" + path + "/file1.txt",
"file1.txt",
"file",
"text/plain",
1024L
);
McpResource resource2 = new McpResource(
"file://" + path + "/file2.txt",
"file2.txt",
"file",
"text/plain",
2048L
);
return new McpActionResponse(true, Map.of("path", path), List.of(resource1, resource2), null, 0);
} else if ("read_resource".equals(action)) {
String uri = (String) params.get("uri");
if (uri != null) {
return new McpActionResponse(
true,
Map.of("uri", uri, "content", "Sample content from " + uri),
List.of(),
null,
0
);
}
}
return new McpActionResponse(false, Map.of(), List.of(), "Unknown action: " + action, 0);
}
private McpActionResponse executeProcessAction(McpActionRequest request) {
String action = request.action();
if ("list_processes".equals(action)) {
return new McpActionResponse(
true,
Map.of("count", 3),
List.of(),
null,
0
);
}
return new McpActionResponse(false, Map.of(), List.of(), "Unknown action: " + action, 0);
}
private McpActionResponse executeHttpAction(McpActionRequest request) {
String action = request.action();
if ("get".equals(action)) {
String url = (String) request.parameters().get("url");
return new McpActionResponse(
true,
Map.of("url", url, "status", 200, "body", "Sample response"),
List.of(),
null,
0
);
}
return new McpActionResponse(false, Map.of(), List.of(), "Unknown action: " + action, 0);
}
private McpActionResponse executeGenericAction(McpActionRequest request, McpServiceConfig config) {
return new McpActionResponse(
true,
Map.of("service", config.name(), "action", request.action()),
List.of(),
null,
0
);
}
}