Skip to content

Commit 6eaebcb

Browse files
authored
Merge pull request #617 from TencentCloudBase/automation/attribution-issue-mo8z2h9t-o13t7d-mcp
fix: MCP 查询云函数日志工具参数校验错误或提示不清晰
2 parents f83161b + 082d4dc commit 6eaebcb

1 file changed

Lines changed: 67 additions & 17 deletions

File tree

mcp/src/tools/functions.ts

Lines changed: 67 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,8 @@ export function registerFunctionTools(server: ExtendedMcpServer) {
494494
}
495495
};
496496

497+
const TIME_FORMAT_REGEX = /^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}$/;
498+
497499
const validateLogRange = (
498500
startTime?: string,
499501
endTime?: string,
@@ -504,6 +506,17 @@ export function registerFunctionTools(server: ExtendedMcpServer) {
504506
throw new Error("offset+limit 不能大于 10000");
505507
}
506508

509+
if (startTime && !TIME_FORMAT_REGEX.test(startTime)) {
510+
throw new Error(
511+
`startTime 格式错误: "${startTime}"。必须使用 YYYY-MM-DD HH:mm:ss 格式(如 2024-01-01 00:00:00)`,
512+
);
513+
}
514+
if (endTime && !TIME_FORMAT_REGEX.test(endTime)) {
515+
throw new Error(
516+
`endTime 格式错误: "${endTime}"。必须使用 YYYY-MM-DD HH:mm:ss 格式(如 2024-01-01 23:59:59)`,
517+
);
518+
}
519+
507520
if (startTime && endTime) {
508521
const start = new Date(startTime).getTime();
509522
const end = new Date(endTime).getTime();
@@ -611,15 +624,30 @@ export function registerFunctionTools(server: ExtendedMcpServer) {
611624
input.limit,
612625
);
613626
const cloudbase = await getManager();
614-
const result = await cloudbase.functions.getFunctionLogsV2({
615-
name: input.functionName,
616-
offset: input.offset,
617-
limit: input.limit,
618-
startTime: input.startTime,
619-
endTime: input.endTime,
620-
requestId: input.requestId,
621-
qualifier: input.qualifier,
622-
});
627+
let result;
628+
try {
629+
result = await cloudbase.functions.getFunctionLogsV2({
630+
name: input.functionName,
631+
offset: input.offset,
632+
limit: input.limit,
633+
startTime: input.startTime,
634+
endTime: input.endTime,
635+
requestId: input.requestId,
636+
qualifier: input.qualifier,
637+
});
638+
} catch (error) {
639+
const errMsg = error instanceof Error ? error.message : String(error);
640+
if (/invalid parameter/i.test(errMsg)) {
641+
throw new Error(
642+
`${errMsg}\n\n常见原因:\n` +
643+
`1. startTime/endTime 格式错误,必须为 YYYY-MM-DD HH:mm:ss(如 2024-01-01 00:00:00),不支持 ISO 8601 或时间戳\n` +
644+
`2. startTime 和 endTime 间隔超过一天\n` +
645+
`3. functionName 不存在或格式不正确\n` +
646+
`建议:不传 startTime/endTime 时默认查询最近一天的日志。`,
647+
);
648+
}
649+
throw error;
650+
}
623651
logCloudBaseResult(server.logger, result);
624652
return buildEnvelope(
625653
{
@@ -645,11 +673,25 @@ export function registerFunctionTools(server: ExtendedMcpServer) {
645673
}
646674
validateLogRange(input.startTime, input.endTime);
647675
const cloudbase = await getManager();
648-
const result = await cloudbase.functions.getFunctionLogDetail({
649-
startTime: input.startTime,
650-
endTime: input.endTime,
651-
logRequestId: input.requestId,
652-
});
676+
let result;
677+
try {
678+
result = await cloudbase.functions.getFunctionLogDetail({
679+
startTime: input.startTime,
680+
endTime: input.endTime,
681+
logRequestId: input.requestId,
682+
});
683+
} catch (error) {
684+
const errMsg = error instanceof Error ? error.message : String(error);
685+
if (/invalid parameter/i.test(errMsg)) {
686+
throw new Error(
687+
`${errMsg}\n\n常见原因:\n` +
688+
`1. startTime/endTime 格式错误,必须为 YYYY-MM-DD HH:mm:ss(如 2024-01-01 00:00:00),不支持 ISO 8601 或时间戳\n` +
689+
`2. startTime 和 endTime 间隔超过一天\n` +
690+
`建议:不传 startTime/endTime 时默认查询最近一天的日志。`,
691+
);
692+
}
693+
throw error;
694+
}
653695
logCloudBaseResult(server.logger, result);
654696
return buildEnvelope(
655697
{
@@ -1442,12 +1484,20 @@ export function registerFunctionTools(server: ExtendedMcpServer) {
14421484
action: z
14431485
.enum(QUERY_FUNCTION_ACTIONS)
14441486
.describe("只读操作类型,例如 listFunctions、getFunctionDetail、listFunctionLogs"),
1445-
functionName: z.string().optional().describe("函数名称。函数相关 action 必填"),
1487+
functionName: z.string().optional().describe(
1488+
"函数名称。listFunctionLogs、getFunctionDetail、listFunctionLayers、listFunctionTriggers、getFunctionDownloadUrl 时必填",
1489+
),
14461490
limit: z.number().optional().describe("分页数量。列表类 action 可选"),
14471491
offset: z.number().optional().describe("分页偏移。列表类 action 可选"),
14481492
codeSecret: z.string().optional().describe("代码保护密钥"),
1449-
startTime: z.string().optional().describe("日志查询开始时间"),
1450-
endTime: z.string().optional().describe("日志查询结束时间"),
1493+
startTime: z.string().optional().describe(
1494+
"日志查询开始时间,格式必须为 YYYY-MM-DD HH:mm:ss(如 2024-01-01 00:00:00)。" +
1495+
"与 endTime 间隔不能超过一天。不传时默认查询最近一天",
1496+
),
1497+
endTime: z.string().optional().describe(
1498+
"日志查询结束时间,格式必须为 YYYY-MM-DD HH:mm:ss(如 2024-01-01 23:59:59)。" +
1499+
"与 startTime 间隔不能超过一天。不传时默认为当前时间",
1500+
),
14511501
requestId: z.string().optional().describe("日志 requestId。获取日志详情时必填"),
14521502
qualifier: z.string().optional().describe("函数版本,日志查询时可选"),
14531503
runtime: z.string().optional().describe("层查询的运行时筛选"),

0 commit comments

Comments
 (0)