feat: standardize tool names by pod domain action
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 1m55s
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 1m55s
This commit is contained in:
20
README.md
20
README.md
@@ -535,7 +535,7 @@ src/main/resources/
|
||||
|
||||
```java
|
||||
@McpFunction(
|
||||
name = "sample.claim.search.resource",
|
||||
name = "oth.cmm.claim.search",
|
||||
inputSchemaResource = "classpath:tool-schemas/cmm/claim-search-resource-input-schema.json",
|
||||
outputSchemaResource = "classpath:tool-schemas/cmm/claim-search-resource-output-schema.json"
|
||||
)
|
||||
@@ -570,3 +570,21 @@ Tool 실행이 끝나면 아래 로그는 Schema 정의가 아니라 **검증을
|
||||
```powershell
|
||||
.\gradlew.bat :dap-tool-oth:test --tests "io.shinhanlife.dap.mcc.biz.cmm.dto.ClaimSearchRequestSchemaTest"
|
||||
```
|
||||
|
||||
### Tool Naming Convention
|
||||
|
||||
All Tool names use the four-level lowercase format `pod.domain.service.action`. Do not use underscores or CamelCase; use a hyphen (`-`) only when a single level has multiple words.
|
||||
|
||||
- `pod`: deployment Tool Pod/module (`dap-tool-oth` → `oth`, `dap-tool-sms` → `sms`)
|
||||
- `domain`: business-domain package (`cmm`, `smp`, `sol`, etc.)
|
||||
- `service`: business service or resource
|
||||
- `action`: the requested operation (`search`, `list`, `detail`, `issue`, `inquiry`, etc.)
|
||||
|
||||
```text
|
||||
oth.cmm.bond.issue
|
||||
oth.cmm.claim.search
|
||||
oth.sol.request.list
|
||||
oth.smp.weather.inquiry
|
||||
```
|
||||
|
||||
When Scaffold receives `dap-tool-oth`, `cmm`, and `ClaimSearch`, it generates `oth.cmm.claim.search`. The `validateMcpToolNames` Gradle task rejects both a duplicate name and any name outside this format before packaging, including its source file and line number.
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
@@ -199,8 +200,7 @@ public class ToolScaffolder {
|
||||
""".formatted(bizPackage, bizPackage, baseName, author, createDate, createDate, author, baseName);
|
||||
Files.writeString(dtoDir.resolve(baseName + "Response.java"), resContent);
|
||||
|
||||
String rawToolName = baseName.isEmpty() ? baseName : Character.toLowerCase(baseName.charAt(0)) + baseName.substring(1);
|
||||
String toolName = group.toLowerCase() + "." + rawToolName;
|
||||
String toolName = toToolName(moduleName, group, baseName);
|
||||
|
||||
String serviceInterfaceContent = """
|
||||
package %s.usecase;
|
||||
@@ -672,6 +672,24 @@ public class ToolScaffolder {
|
||||
return log.toString();
|
||||
}
|
||||
|
||||
private static String toToolName(String moduleName, String group, String baseName) {
|
||||
String pod = moduleName.startsWith("dap-tool-")
|
||||
? moduleName.substring("dap-tool-".length())
|
||||
: "oth";
|
||||
String normalizedName = baseName.replaceAll("([a-z0-9])([A-Z])", "$1 $2")
|
||||
.toLowerCase(Locale.ROOT)
|
||||
.replaceAll("[^a-z0-9]+", " ")
|
||||
.trim();
|
||||
String[] words = normalizedName.split("\\s+");
|
||||
String service = words[0];
|
||||
String action = words.length == 1 ? "execute" : words[words.length - 1];
|
||||
return "%s.%s.%s.%s".formatted(
|
||||
pod.toLowerCase(Locale.ROOT),
|
||||
group.toLowerCase(Locale.ROOT),
|
||||
service,
|
||||
action);
|
||||
}
|
||||
|
||||
private static String toPascalCase(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return str;
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.regex.Pattern;
|
||||
public final class McpToolNameValidator {
|
||||
|
||||
private static final Pattern TOOL_NAME_PATTERN = Pattern.compile("\\bname\\s*=\\s*\\\"([^\\\"]+)\\\"");
|
||||
private static final Pattern TOOL_NAME_CONVENTION = Pattern.compile("^[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*$");
|
||||
|
||||
private McpToolNameValidator() {
|
||||
}
|
||||
@@ -45,6 +46,14 @@ public final class McpToolNameValidator {
|
||||
throw new UncheckedIOException("Failed to scan MCP tool modules", exception);
|
||||
}
|
||||
|
||||
List<Map.Entry<String, List<ToolDeclaration>>> invalidNames = declarationsByName.entrySet().stream()
|
||||
.filter(entry -> !TOOL_NAME_CONVENTION.matcher(entry.getKey()).matches())
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.toList();
|
||||
|
||||
if (!invalidNames.isEmpty()) {
|
||||
throw new IllegalStateException(buildInvalidNameMessage(invalidNames));
|
||||
}
|
||||
List<Map.Entry<String, List<ToolDeclaration>>> duplicates = declarationsByName.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().size() > 1)
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
@@ -129,6 +138,21 @@ public final class McpToolNameValidator {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static String buildInvalidNameMessage(List<Map.Entry<String, List<ToolDeclaration>>> invalidNames) {
|
||||
StringBuilder message = new StringBuilder("Invalid MCP tool name(s): expected pod.domain.service.action using lowercase letters, digits, or hyphens.");
|
||||
for (Map.Entry<String, List<ToolDeclaration>> invalidName : invalidNames) {
|
||||
message.append("\n\n").append(invalidName.getKey());
|
||||
invalidName.getValue().stream()
|
||||
.sorted(Comparator.comparing(ToolDeclaration::moduleName).thenComparing(declaration -> declaration.source().toString()))
|
||||
.forEach(declaration -> message.append("\n- ")
|
||||
.append(declaration.moduleName())
|
||||
.append(": ")
|
||||
.append(declaration.source())
|
||||
.append(':').append(declaration.line()));
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
private static String buildDuplicateMessage(List<Map.Entry<String, List<ToolDeclaration>>> duplicates) {
|
||||
StringBuilder message = new StringBuilder("Duplicate MCP tool name(s):");
|
||||
for (Map.Entry<String, List<ToolDeclaration>> duplicate : duplicates) {
|
||||
|
||||
@@ -19,7 +19,7 @@ class ToolScaffolderTest {
|
||||
String useCase = Files.readString(root.resolve("usecase/ClaimSearchUseCase.java"));
|
||||
String response = Files.readString(root.resolve("dto/ClaimSearchResponse.java"));
|
||||
|
||||
assertTrue(useCase.contains("name = \"cmm.claimSearch\""));
|
||||
assertTrue(useCase.contains("name = \"oth.cmm.claim.search\""));
|
||||
assertTrue(useCase.contains("version = \"1.0.0\""));
|
||||
assertTrue(useCase.contains("timeoutMillis = 300000L"));
|
||||
assertTrue(response.contains("@McpOutputSchema"));
|
||||
|
||||
@@ -74,7 +74,7 @@ class ToolSchemaResolverTest {
|
||||
static class InlineSchemaTool {
|
||||
@McpFunction(
|
||||
displayName = "inline",
|
||||
name = "sample.inline",
|
||||
name = "test.schema.inline",
|
||||
description = "inline schema",
|
||||
inputSchema = "{\"type\":\"object\",\"properties\":{\"keyword\":{\"type\":\"string\"}},\"additionalProperties\":false}")
|
||||
void search(AutomaticRequest request) {
|
||||
@@ -82,13 +82,13 @@ class ToolSchemaResolverTest {
|
||||
}
|
||||
|
||||
static class AutomaticSchemaTool {
|
||||
@McpFunction(displayName = "automatic", name = "sample.automatic", description = "automatic schema")
|
||||
@McpFunction(displayName = "automatic", name = "test.schema.automatic", description = "automatic schema")
|
||||
void search(AutomaticRequest request) {
|
||||
}
|
||||
}
|
||||
|
||||
static class AutomaticOutputSchemaTool {
|
||||
@McpFunction(displayName = "automatic-output", name = "sample.automatic-output", description = "automatic output")
|
||||
@McpFunction(displayName = "automatic-output", name = "test.schema.automatic-output", description = "automatic output")
|
||||
SimpleResponse search(AutomaticRequest request) {
|
||||
return null;
|
||||
}
|
||||
@@ -106,7 +106,7 @@ class ToolSchemaResolverTest {
|
||||
static class OutputSchemaTool {
|
||||
@McpFunction(
|
||||
displayName = "output",
|
||||
name = "sample.output",
|
||||
name = "test.schema.output",
|
||||
description = "output schema",
|
||||
outputSchema = "{\"type\":\"object\",\"properties\":{\"resultCode\":{\"type\":\"string\"}},\"required\":[\"resultCode\"],\"additionalProperties\":false}")
|
||||
void search(AutomaticRequest request) {
|
||||
|
||||
@@ -31,26 +31,36 @@ class McpToolNameValidatorTest {
|
||||
|
||||
@Test
|
||||
void rejectsDuplicateMcpFunctionNamesAcrossToolModules() throws IOException {
|
||||
writeToolSource("dap-tool-first", "FirstTool.java", "first", "send_sms");
|
||||
writeToolSource("dap-tool-second", "SecondTool.java", "second", "send_sms");
|
||||
writeToolSource("dap-tool-first", "FirstTool.java", "first", "oth.sms.notification.send");
|
||||
writeToolSource("dap-tool-second", "SecondTool.java", "second", "oth.sms.notification.send");
|
||||
|
||||
IllegalStateException exception = assertThrows(IllegalStateException.class,
|
||||
() -> McpToolNameValidator.assertUnique(temporaryRoot));
|
||||
|
||||
assertTrue(exception.getMessage().contains("send_sms"));
|
||||
assertTrue(exception.getMessage().contains("oth.sms.notification.send"));
|
||||
assertTrue(exception.getMessage().contains("dap-tool-first"));
|
||||
assertTrue(exception.getMessage().contains("dap-tool-second"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void validationRunnerRejectsDuplicateMcpFunctionNamesBeforePackaging() throws IOException {
|
||||
writeToolSource("dap-tool-first", "FirstTool.java", "first", "send_sms");
|
||||
writeToolSource("dap-tool-second", "SecondTool.java", "second", "send_sms");
|
||||
writeToolSource("dap-tool-first", "FirstTool.java", "first", "oth.sms.notification.send");
|
||||
writeToolSource("dap-tool-second", "SecondTool.java", "second", "oth.sms.notification.send");
|
||||
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> McpToolNameValidationRunner.validate(temporaryRoot));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsToolNameOutsidePodDomainServiceActionConvention() throws IOException {
|
||||
writeToolSource("dap-tool-first", "FirstTool.java", "first", "bond_issue");
|
||||
|
||||
IllegalStateException exception = assertThrows(IllegalStateException.class,
|
||||
() -> McpToolNameValidator.assertUnique(temporaryRoot));
|
||||
|
||||
assertTrue(exception.getMessage().contains("Invalid MCP tool name(s)"));
|
||||
assertTrue(exception.getMessage().contains("bond_issue"));
|
||||
}
|
||||
@Test
|
||||
void acceptsCurrentProjectToolNames() {
|
||||
assertDoesNotThrow(() -> McpToolNameValidator.assertUnique(findProjectRoot()));
|
||||
@@ -61,11 +71,11 @@ class McpToolNameValidatorTest {
|
||||
Path root = findProjectRoot();
|
||||
|
||||
assertToolName(root, "dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/CustomerInfoUseCase.java",
|
||||
"customer_detail", "detail");
|
||||
"oth.cmm.customer.detail", "detail");
|
||||
assertToolName(root, "dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/BillingProcessUseCase.java",
|
||||
"billing_process", "process");
|
||||
"oth.cmm.billing.process", "process");
|
||||
assertToolName(root, "dap-tool-oth/src/main/java/io/shinhanlife/dap/mcc/biz/cmm/usecase/BondIssueUseCase.java",
|
||||
"bond_issue", "issue");
|
||||
"oth.cmm.bond.issue", "issue");
|
||||
}
|
||||
|
||||
private void assertToolName(Path root, String relativePath, String expectedName, String legacyName) throws IOException {
|
||||
|
||||
@@ -6,7 +6,7 @@ import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
@McpTool(routingType = "MCI", categoryKey = "cmm")
|
||||
public interface BalanceUseCase {
|
||||
@McpFunction(register = false, displayName = "balance 툴", name = "balance",
|
||||
@McpFunction(register = false, displayName = "balance 툴", name = "oth.cmm.balance.inquiry",
|
||||
description = "고객의 계좌 잔액을 조회합니다.",
|
||||
prompt = "고객 계좌 잔액을 조회해줘.",
|
||||
mappingId = "ACC_001"
|
||||
|
||||
@@ -6,11 +6,11 @@ import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
@McpTool(
|
||||
routingType = "MCI",
|
||||
categoryKey = "claim"
|
||||
categoryKey = "cmm"
|
||||
)
|
||||
public interface BillingProcessUseCase {
|
||||
Object getStatus(BillingStatusRequest req);
|
||||
|
||||
@McpFunction(register = false, displayName = "process 툴", name = "billing_process", description = "청구 처리", prompt = "현재 접수된 청구건에 대한 심사 처리를 진행해.", mappingId = "BILL_002")
|
||||
@McpFunction(register = false, displayName = "process 툴", name = "oth.cmm.billing.process", description = "청구 처리", prompt = "현재 접수된 청구건에 대한 심사 처리를 진행해.", mappingId = "BILL_002")
|
||||
Object processBilling(BillingProcessRequest data);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
@McpTool(
|
||||
routingType = "EAI",
|
||||
categoryKey = "policy"
|
||||
categoryKey = "cmm"
|
||||
)
|
||||
public interface BondIssueUseCase {
|
||||
Object check(BondCheckRequest req);
|
||||
|
||||
@McpFunction(displayName = "issue 툴", name = "bond_issue", register = false, description = "증권 발행 테스트1", prompt = "디지털 증권 발행 프로세스를 실행해.", mappingId = "BOND_002")
|
||||
@McpFunction(displayName = "issue 툴", name = "oth.cmm.bond.issue", register = false, description = "증권 발행 테스트1", prompt = "디지털 증권 발행 프로세스를 실행해.", mappingId = "BOND_002")
|
||||
Object issue(BondIssueRequest data);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public interface ClaimSearchSchemaSampleUseCase {
|
||||
@McpFunction(
|
||||
register = false,
|
||||
displayName = "Claim search JSON Schema sample",
|
||||
name = "sample.claim.search.resource",
|
||||
name = "oth.cmm.claim.search",
|
||||
description = "Claim search Tool sample using input and output JSON Schema resources.",
|
||||
prompt = "Search an insurance claim by claim number or contract number.",
|
||||
inputSchemaResource = "classpath:tool-schemas/cmm/claim-search-resource-input-schema.json",
|
||||
|
||||
@@ -6,14 +6,14 @@ import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
@McpTool(
|
||||
routingType = "HTTP",
|
||||
categoryKey = "hr"
|
||||
categoryKey = "cmm"
|
||||
)
|
||||
public interface CommonUtilityUseCase {
|
||||
Object registerVacation(VacationRegisterRequest req);
|
||||
|
||||
@McpFunction(register = false, displayName = "get_leave_count 툴", name = "get_leave_count", description = "연차 갯수 조회", prompt = "현재 사용 가능한 남은 연차 일수를 알려줘.", mappingId = "HR_VAC_02")
|
||||
@McpFunction(register = false, displayName = "get_leave_count 툴", name = "oth.cmm.leave.count", description = "연차 갯수 조회", prompt = "현재 사용 가능한 남은 연차 일수를 알려줘.", mappingId = "HR_VAC_02")
|
||||
Object getLeaveCount(LeaveCountRequest data);
|
||||
|
||||
@McpFunction(register = false, displayName = "secret_tool 툴", name = "secret_tool", description = "비공개 툴 테스트", prompt = "숨겨진 툴 강제 호출", mappingId = "SECRET_001", visible = false)
|
||||
@McpFunction(register = false, displayName = "secret_tool 툴", name = "oth.cmm.secret.execute", description = "비공개 툴 테스트", prompt = "숨겨진 툴 강제 호출", mappingId = "SECRET_001", visible = false)
|
||||
Object secretTool(LeaveCountRequest data);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
@McpTool(
|
||||
routingType = "HTTP",
|
||||
categoryKey = "contract"
|
||||
categoryKey = "cmm"
|
||||
)
|
||||
public interface ContractInquiryUseCase {
|
||||
Object getStatus(ContractStatusRequest req);
|
||||
|
||||
@McpFunction(register = false, displayName = "contract_detail 툴", name = "contract_detail", description = "계약상세 조회", prompt = "김신한 고객의 계약 상세 내역을 알려줘.", mappingId = "CNTR_002")
|
||||
@McpFunction(register = false, displayName = "contract_detail 툴", name = "oth.cmm.contract.detail", description = "계약상세 조회", prompt = "김신한 고객의 계약 상세 내역을 알려줘.", mappingId = "CNTR_002")
|
||||
Object getDetail(ContractDetailRequest data);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import io.shinhanlife.dap.mcc.biz.cmm.dto.*;
|
||||
|
||||
@McpTool(
|
||||
routingType = "TCP",
|
||||
categoryKey = "customer"
|
||||
categoryKey = "cmm"
|
||||
)
|
||||
public interface CustomerInfoUseCase {
|
||||
Object getGrade(CustomerGradeRequest req);
|
||||
|
||||
@McpFunction(register = false, displayName = "detail 툴", name = "customer_detail", description = "고객상세 정보 조회", prompt = "이 고객의 상세 기본정보(주소, 연락처 등)를 알려줘.", mappingId = "CRM_002")
|
||||
@McpFunction(register = false, displayName = "detail 툴", name = "oth.cmm.customer.detail", description = "고객상세 정보 조회", prompt = "이 고객의 상세 기본정보(주소, 연락처 등)를 알려줘.", mappingId = "CRM_002")
|
||||
Object getDetail(CustomerDetailRequest data);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import io.shinhanlife.dap.mcc.biz.cmm.dto.MetaCommonCodeRequest;
|
||||
public interface MetaCommonCodeUseCase {
|
||||
@McpFunction(
|
||||
displayName = "메타 통합코드 조회 툴",
|
||||
name = "metaCommonCode",
|
||||
name = "oth.cmm.common-code.lookup",
|
||||
description = "메타 통합코드 목록을 조회해줘",
|
||||
prompt = "메타 통합코드 목록을 조회해줘",
|
||||
mappingId = "CLCNNB00001",
|
||||
|
||||
@@ -25,7 +25,7 @@ import io.shinhanlife.dap.mcc.biz.cmm.dto.MetaTableRequest;
|
||||
public interface MetaTableUseCase {
|
||||
@McpFunction(
|
||||
displayName = "메타 테이블 조회 툴",
|
||||
name = "metaTable",
|
||||
name = "oth.cmm.meta.table",
|
||||
description = "메타 테이블 정보 목록을 조회해줘",
|
||||
prompt = "메타 테이블 정보 목록을 조회해줘",
|
||||
mappingId = "CLCNNB00001",
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.Map;
|
||||
public interface TemplateUtilityUseCase {
|
||||
@McpFunction(
|
||||
displayName = "템플릿 유틸리티",
|
||||
name = "get_template_file_url",
|
||||
name = "oth.cmm.template.url",
|
||||
description = "요청한 템플릿(엑셀, 워드 등) 파일(양식)을 다운로드 받을 수 있는 시스템 URL을 반환합니다. AI는 이 URL을 사용자에게 마크다운 링크 형태로 제공해야 합니다.",
|
||||
prompt = "요청하신 템플릿 양식 파일 다운로드 URL은 다음과 같습니다. 클릭하여 다운로드하세요:"
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ import io.shinhanlife.dap.mcc.biz.smp.dto.DailyQuoteResponse;
|
||||
categoryKey = "smp"
|
||||
)
|
||||
public interface DailyQuoteToolUseCase {
|
||||
@McpFunction(register = false, displayName = "랜덤 명언 툴", name = "daily_quote",
|
||||
@McpFunction(register = false, displayName = "랜덤 명언 툴", name = "oth.smp.quote.daily",
|
||||
description = "무작위로 영감을 주는 명언을 하나 가져옵니다.",
|
||||
prompt = "오늘의 명언 하나 알려줘, 동기부여 명언 등",
|
||||
mappingId = "QUOTE_001"
|
||||
|
||||
@@ -12,7 +12,7 @@ import io.shinhanlife.dap.mcc.biz.smp.dto.ExchangeRateResponse;
|
||||
categoryKey = "smp"
|
||||
)
|
||||
public interface ExchangeRateToolUseCase {
|
||||
@McpFunction(register = false, displayName = "실시간 환율 조회 툴", name = "exchange_rate",
|
||||
@McpFunction(register = false, displayName = "실시간 환율 조회 툴", name = "oth.smp.exchange-rate.inquiry",
|
||||
description = "원하는 통화의 실시간 환율을 조회합니다. (예: USD, EUR, JPY)",
|
||||
prompt = "현재 달러 환율 알려줘, 엔화 환율은?",
|
||||
mappingId = "EXCHANGE_001"
|
||||
|
||||
@@ -11,7 +11,7 @@ import io.shinhanlife.dap.mcc.biz.smp.dto.TeamMemberRequest;
|
||||
public interface TeamMemberUseCase {
|
||||
@McpFunction(
|
||||
displayName = "신한라이프 MCP, TOOL 파트 구성원 조회",
|
||||
name = "get_smp_members",
|
||||
name = "oth.smp.team.list",
|
||||
description = "신한라이프 MCP, TOOL 파트 구성원을 조회합니다.",
|
||||
prompt = "신한라이프 MCP, TOOL 파트 구성원을 조회해 줘. (주의: 응답 시 ** 등 마크다운 기호를 절대 사용하지 말고 평문으로만 출력해 줘)",
|
||||
mappingId = "DIRECT0001",
|
||||
|
||||
@@ -9,7 +9,7 @@ import io.shinhanlife.dap.mcc.biz.smp.dto.*;
|
||||
categoryKey = "smp"
|
||||
)
|
||||
public interface WeatherToolUseCase {
|
||||
@McpFunction(register = false, displayName = "날씨 조회 툴", name = "weather",
|
||||
@McpFunction(register = false, displayName = "날씨 조회 툴", name = "oth.smp.weather.inquiry",
|
||||
description = "특정 도시의 현재 날씨, 온도, 풍속 정보를 조회합니다.",
|
||||
prompt = "서울 날씨 알려줘, 부산 기온 알려줘 등 실시간 기상 조회",
|
||||
mappingId = "WEATHER_001"
|
||||
|
||||
@@ -26,7 +26,7 @@ public interface SolReqDetailUseCase {
|
||||
|
||||
@McpFunction(
|
||||
displayName = "SolReqDetail 툴",
|
||||
name = "solReqDetail",
|
||||
name = "oth.sol.request.detail",
|
||||
description = "SOL 의뢰서 상세 조회",
|
||||
prompt = "SOL 의뢰서 상세 조회해줘",
|
||||
mappingId = "SOLG00000002",
|
||||
|
||||
@@ -11,7 +11,7 @@ import io.shinhanlife.dap.mcc.biz.sol.dto.SolReqListRequest;
|
||||
public interface SolReqListUseCase {
|
||||
@McpFunction(
|
||||
displayName = "SolReqList 툴",
|
||||
name = "solReqList",
|
||||
name = "oth.sol.request.list",
|
||||
description = "SOL 의뢰서 목록 조회해줘",
|
||||
prompt = "SOL 의뢰서 목록 조회해줘",
|
||||
mappingId = "SOLG00000001",
|
||||
|
||||
Reference in New Issue
Block a user