diff --git a/cs25-service/src/main/java/com/example/cs25service/domain/ai/service/BraveSearchMcpService.java b/cs25-service/src/main/java/com/example/cs25service/domain/ai/service/BraveSearchMcpService.java index 4f6bb103..d11ca3f3 100644 --- a/cs25-service/src/main/java/com/example/cs25service/domain/ai/service/BraveSearchMcpService.java +++ b/cs25-service/src/main/java/com/example/cs25service/domain/ai/service/BraveSearchMcpService.java @@ -6,7 +6,6 @@ import io.modelcontextprotocol.spec.McpSchema.CallToolRequest; import io.modelcontextprotocol.spec.McpSchema.CallToolResult; import io.modelcontextprotocol.spec.McpSchema.ListToolsResult; -import java.time.Duration; import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; @@ -19,8 +18,9 @@ public class BraveSearchMcpService { private static final String BRAVE_WEB_TOOL = "brave_web_search"; - private static final Duration INIT_TIMEOUT = Duration.ofSeconds(60); + private final List mcpClients; + private final ObjectMapper objectMapper; public JsonNode search(String query, int count, int offset) { @@ -36,40 +36,28 @@ public JsonNode search(String query, int count, int offset) { JsonNode content = objectMapper.valueToTree(result.content()); log.info("[Brave MCP Response Raw content]: {}", content.toPrettyString()); + if (content != null && content.isArray()) { var root = objectMapper.createObjectNode(); root.set("results", content); return root; - } - } - private void ensureInitialized(McpSyncClient client) { - if (!client.isInitialized()) { - synchronized (client) { // 다중 스레드 초기화 경합 방지 - if (!client.isInitialized()) { - log.debug("MCP 클라이언트 초기화 시작…"); - client.initialize(); // 매개변수 없는 버전 - log.debug("MCP 클라이언트 초기화 완료"); - } - } - } + return content != null ? content : objectMapper.createObjectNode(); } private McpSyncClient resolveBraveClient() { for (McpSyncClient client : mcpClients) { - try { - ensureInitialized(client); // 초기화 - ListToolsResult tools = client.listTools(); - if (tools != null && tools.tools() != null && - tools.tools().stream() - .anyMatch(t -> BRAVE_WEB_TOOL.equalsIgnoreCase(t.name()))) { + ListToolsResult tools = client.listTools(); + if (tools != null && tools.tools() != null) { + boolean found = tools.tools().stream() + .anyMatch(tool -> BRAVE_WEB_TOOL.equalsIgnoreCase(tool.name())); + if (found) { return client; } - } catch (Exception e) { - log.debug("Brave MCP 클라이언트 후보 실패: {}", e.toString()); } } - throw new IllegalStateException("Brave MCP 서버에서 '" + BRAVE_WEB_TOOL + "' 툴을 찾을 수 없습니다."); + + throw new IllegalStateException("Brave MCP 서버에서 brave_web_search 툴을 찾을 수 없습니다."); } } \ No newline at end of file diff --git a/cs25-service/src/main/resources/application.properties b/cs25-service/src/main/resources/application.properties index d7a99e7b..f5ea13aa 100644 --- a/cs25-service/src/main/resources/application.properties +++ b/cs25-service/src/main/resources/application.properties @@ -65,12 +65,14 @@ spring.ai.chat.client.enabled=false # MCP spring.ai.mcp.client.enabled=true spring.ai.mcp.client.type=SYNC -spring.ai.mcp.client.request-timeout=45s +spring.ai.mcp.client.request-timeout=60s spring.ai.mcp.client.root-change-notification=false # STDIO Connect: Brave Search -spring.ai.mcp.client.stdio.connections.brave.command=/usr/local/bin/server-brave-search +spring.ai.mcp.client.stdio.connections.brave.command=server-brave-search spring.ai.mcp.client.stdio.connections.brave.args[0]=--stdio spring.ai.mcp.client.stdio.connections.brave.env.BRAVE_API_KEY=${BRAVE_API_KEY} +spring.ai.mcp.client.initialized=false +spring.autoconfigure.exclude=org.springframework.ai.model.tool.autoconfigure.ToolCallingAutoConfiguration #MAIL spring.mail.host=smtp.gmail.com spring.mail.port=587