-
Notifications
You must be signed in to change notification settings - Fork 936
Expand file tree
/
Copy pathmcp-tools.ts
More file actions
86 lines (79 loc) · 2.72 KB
/
mcp-tools.ts
File metadata and controls
86 lines (79 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { z } from '@midscene/core';
import { getDebug } from '@midscene/shared/logger';
import { BaseMidsceneTools, type ToolDefinition } from '@midscene/shared/mcp';
import { type AndroidAgent, agentFromAdbDevice } from './agent';
import { AndroidDevice } from './device';
const debug = getDebug('mcp:android-tools');
/**
* Android-specific tools manager
* Extends BaseMidsceneTools to provide Android ADB device connection tools
*/
export class AndroidMidsceneTools extends BaseMidsceneTools<AndroidAgent> {
protected createTemporaryDevice() {
// Create minimal temporary instance without connecting to device
// The constructor doesn't establish ADB connection
return new AndroidDevice('temp-for-action-space', {});
}
protected async ensureAgent(deviceId?: string): Promise<AndroidAgent> {
if (this.agent && deviceId) {
// If a specific deviceId is requested and we have an agent,
// destroy it to create a new one with the new device
try {
await this.agent.destroy?.();
} catch (error) {
debug('Failed to destroy agent during cleanup:', error);
}
this.agent = undefined;
}
if (this.agent) {
return this.agent;
}
debug('Creating Android agent with deviceId:', deviceId || 'auto-detect');
const agent = await agentFromAdbDevice(deviceId, {
autoDismissKeyboard: false,
reportFileName: this.getPersistedReportFileName(),
});
this.agent = agent;
this.persistAgentReportFileName(this.agent);
return agent;
}
/**
* Provide Android-specific platform tools
*/
protected preparePlatformTools(): ToolDefinition[] {
return [
{
name: 'android_connect',
description:
'Connect to Android device via ADB. If deviceId not provided, uses the first available device.',
schema: {
deviceId: z
.string()
.optional()
.describe('Android device ID (from adb devices)'),
},
handler: async ({ deviceId }: { deviceId?: string }) => {
const agent = await this.ensureAgent(deviceId);
const screenshot = await agent.page.screenshotBase64();
return {
content: [
{
type: 'text',
text: `Connected to Android device${deviceId ? `: ${deviceId}` : ' (auto-detected)'}`,
},
...this.buildScreenshotContent(screenshot),
],
isError: false,
};
},
},
{
name: 'android_disconnect',
description:
'Disconnect from current Android device and release ADB resources',
schema: {},
handler: this.createDisconnectHandler('Android device'),
},
];
}
}