Skip to content

Commit 6df420b

Browse files
committed
feat(mcp): add StopTool for basic1000 functions
1 parent 075b152 commit 6df420b

File tree

1 file changed

+68
-0
lines changed
  • core/src/main/java/com/taobao/arthas/core/mcp/tool/function/basic1000

1 file changed

+68
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.taobao.arthas.core.mcp.tool.function.basic1000;
2+
3+
import com.taobao.arthas.core.mcp.tool.function.AbstractArthasTool;
4+
import com.taobao.arthas.mcp.server.util.JsonParser;
5+
import com.taobao.arthas.mcp.server.tool.ToolContext;
6+
import com.taobao.arthas.mcp.server.tool.annotation.Tool;
7+
import com.taobao.arthas.mcp.server.tool.annotation.ToolParam;
8+
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
12+
import static com.taobao.arthas.core.mcp.tool.function.StreamableToolUtils.createCompletedResponse;
13+
import static com.taobao.arthas.core.mcp.tool.function.StreamableToolUtils.createErrorResponse;
14+
15+
public class StopTool extends AbstractArthasTool {
16+
17+
public static final int DEFAULT_SHUTDOWN_DELAY_MS = 1000;
18+
19+
@Tool(
20+
name = "stop",
21+
description = "彻底停止 Arthas。注意停止之后不能再调用任何 tool 了。为了确保 MCP client 能收到返回结果,本 tool 会先返回,再延迟执行 stop。"
22+
)
23+
public String stop(
24+
@ToolParam(description = "延迟执行 stop 的毫秒数,默认 1000ms。用于确保 MCP client 收到返回结果。", required = false)
25+
Integer delayMs,
26+
ToolContext toolContext) {
27+
try {
28+
int shutdownDelayMs = getDefaultValue(delayMs, DEFAULT_SHUTDOWN_DELAY_MS);
29+
30+
ToolExecutionContext execContext = new ToolExecutionContext(toolContext, false);
31+
scheduleStop(execContext, shutdownDelayMs);
32+
33+
Map<String, Object> result = new HashMap<>();
34+
result.put("command", "stop");
35+
result.put("scheduled", true);
36+
result.put("delayMs", shutdownDelayMs);
37+
result.put("note", "Arthas 将在返回结果后停止,MCP 连接会断开。");
38+
return JsonParser.toJson(createCompletedResponse("Stop scheduled", result));
39+
} catch (Exception e) {
40+
logger.error("Error scheduling stop", e);
41+
return JsonParser.toJson(createErrorResponse("Error scheduling stop: " + e.getMessage()));
42+
}
43+
}
44+
45+
private void scheduleStop(ToolExecutionContext execContext, int delayMs) {
46+
Object authSubject = execContext.getAuthSubject();
47+
String userId = execContext.getUserId();
48+
49+
Thread shutdownThread = new Thread(() -> {
50+
try {
51+
if (delayMs > 0) {
52+
Thread.sleep(delayMs);
53+
}
54+
} catch (InterruptedException e) {
55+
Thread.currentThread().interrupt();
56+
}
57+
58+
try {
59+
execContext.getCommandContext().getCommandExecutor()
60+
.executeSync("stop", 300000L, null, authSubject, userId);
61+
} catch (Throwable t) {
62+
logger.error("Error executing stop command in background thread", t);
63+
}
64+
}, "arthas-mcp-stop");
65+
shutdownThread.setDaemon(true);
66+
shutdownThread.start();
67+
}
68+
}

0 commit comments

Comments
 (0)