This commit is contained in:
@@ -154,6 +154,11 @@ public class McpRouterController {
|
||||
return activeTools;
|
||||
}
|
||||
|
||||
/** Report 화면처럼 내부 메타데이터 전체가 필요한 Gateway 컴포넌트에 활성 Tool 목록을 제공합니다. */
|
||||
List<ToolMetadata> activeToolsForReport() {
|
||||
return fetchAllActiveTools();
|
||||
}
|
||||
|
||||
@GetMapping("/tools/list")
|
||||
public ResponseEntity<JsonRpcResponse> listTools(
|
||||
@RequestParam(value = "categoryKey", required = false) String categoryKey) {
|
||||
@@ -280,4 +285,4 @@ public class McpRouterController {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.shinhanlife.dap.mcg.presentation;
|
||||
|
||||
import io.shinhanlife.dap.lib.adapter.dto.JsonRpcResponse;
|
||||
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -30,7 +29,7 @@ public class ToolReportProxyController {
|
||||
public ToolReportProxyController(
|
||||
RestClient.Builder restClientBuilder,
|
||||
McpRouterController mcpRouterController,
|
||||
@Value("${report.service-url:http://127.0.0.1:8092}") String reportServiceUrl) {
|
||||
@Value("${report.service-url}") String reportServiceUrl) {
|
||||
this.restClient = restClientBuilder.build();
|
||||
this.mcpRouterController = mcpRouterController;
|
||||
this.reportServiceUrl = reportServiceUrl.replaceAll("/+$", "");
|
||||
@@ -75,18 +74,7 @@ public class ToolReportProxyController {
|
||||
}
|
||||
|
||||
private List<ToolMetadata> activeTools() {
|
||||
ResponseEntity<JsonRpcResponse> response = mcpRouterController.listTools(null);
|
||||
JsonRpcResponse body = response.getBody();
|
||||
if (body == null || !(body.getResult() instanceof Map<?, ?> result)
|
||||
|| !(result.get("tools") instanceof List<?> tools)) {
|
||||
throw new IllegalStateException("MCP tools/list response does not contain result.tools");
|
||||
}
|
||||
return tools.stream().map(item -> {
|
||||
if (!(item instanceof ToolMetadata metadata)) {
|
||||
throw new IllegalStateException("MCP tools/list contains an invalid tool entry");
|
||||
}
|
||||
return metadata;
|
||||
}).toList();
|
||||
return mcpRouterController.activeToolsForReport();
|
||||
}
|
||||
|
||||
private ResponseEntity<byte[]> copy(ResponseEntity<byte[]> response) {
|
||||
|
||||
@@ -52,3 +52,6 @@ mcp:
|
||||
logging:
|
||||
level:
|
||||
org.apache.kafka: ERROR
|
||||
|
||||
report:
|
||||
service-url: ${REPORT_SERVICE_URL:http://127.0.0.1:8092}
|
||||
|
||||
@@ -24,6 +24,9 @@ server:
|
||||
enabled: true
|
||||
shutdown: graceful
|
||||
|
||||
report:
|
||||
service-url: ${REPORT_SERVICE_URL:http://tool-report:8092}
|
||||
|
||||
mcp:
|
||||
gateway:
|
||||
fallback:
|
||||
|
||||
@@ -760,6 +760,7 @@
|
||||
<a href="/chat.html" style="color:#a1a1aa;" class="hover:text-white transition-colors">Chat</a>
|
||||
<a href="/tester.html" style="color:#a1a1aa;" class="hover:text-white transition-colors">Tester</a>
|
||||
<a href="/tool-test-console.html" style="color:#a1a1aa;" class="hover:text-white transition-colors">Console</a>
|
||||
<a href="/tool-report.html" style="color:#a1a1aa;" class="hover:text-white transition-colors">Report</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
|
||||
@@ -156,8 +156,15 @@
|
||||
async function load() {
|
||||
try {
|
||||
const response = await fetch('/report/api/report-tools');
|
||||
if (!response.ok) throw new Error('툴 목록 조회에 실패했습니다.');
|
||||
state.tools = await response.json();
|
||||
const body = await response.json().catch(() => null);
|
||||
if (!response.ok) {
|
||||
throw new Error(body?.error || body?.message || `툴 목록 조회에 실패했습니다. (${response.status})`);
|
||||
}
|
||||
const tools = Array.isArray(body) ? body : body?.result?.tools;
|
||||
if (!Array.isArray(tools)) {
|
||||
throw new Error('툴 목록 응답 형식이 올바르지 않습니다.');
|
||||
}
|
||||
state.tools = tools;
|
||||
[...new Set(state.tools.map(tool => tool.categoryKey))].sort().forEach(category => {
|
||||
const option = document.createElement('option');
|
||||
option.value = category; option.textContent = category; el('category').appendChild(option);
|
||||
|
||||
Reference in New Issue
Block a user