@fortemate/vega-vvd-driver 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/mcp.js +25 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,6 +92,8 @@ Then ask, for example: "Open Settings in the app on the Virtual Device, turn the
|
|
|
92
92
|
|
|
93
93
|
A model chooses the arguments, so they are bounded: at most 100 key presses per call, recordings of up to 600 seconds, and `record_video` writes only a new `.mp4`, `.mov` or `.mkv` file, unless it is told to `overwrite` one. When the client cancels a call, its presses, wait or recording stop. `vvd mcp --pid <n>` ties the server to one device.
|
|
94
94
|
|
|
95
|
+
Each tool declares MCP annotations, for a client that asks before a call that changes something. Four tools only read. `enable_grpc` only turns on the emulator's gRPC endpoint. `press_keys` and `record_video` are marked destructive: a key press can confirm a delete in the app on screen, and `overwrite` replaces a file. None reaches beyond the local device.
|
|
96
|
+
|
|
95
97
|
## As a library
|
|
96
98
|
|
|
97
99
|
```ts
|
package/dist/mcp.js
CHANGED
|
@@ -71,7 +71,7 @@ export const createServer = (options = {}) => {
|
|
|
71
71
|
server.registerTool('list_devices', {
|
|
72
72
|
title: 'List running Vega Virtual Devices',
|
|
73
73
|
description: 'Lists the running Vega Virtual Devices whose gRPC endpoint is on. An empty list usually means gRPC is off: call enable_grpc.',
|
|
74
|
-
annotations: { readOnlyHint: true },
|
|
74
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
75
75
|
}, async () => {
|
|
76
76
|
const devices = findEmulators({ directories: options.directories }).map(({ pid, grpcPort, consolePort, avdName }) => ({
|
|
77
77
|
pid,
|
|
@@ -101,6 +101,12 @@ export const createServer = (options = {}) => {
|
|
|
101
101
|
.optional()
|
|
102
102
|
.describe('The emulator console, an even port; default 5554'),
|
|
103
103
|
},
|
|
104
|
+
annotations: {
|
|
105
|
+
readOnlyHint: false,
|
|
106
|
+
destructiveHint: false,
|
|
107
|
+
idempotentHint: true,
|
|
108
|
+
openWorldHint: false,
|
|
109
|
+
},
|
|
104
110
|
}, async ({ grpc_port, console_port }) => {
|
|
105
111
|
try {
|
|
106
112
|
await enableGrpc(grpc_port ?? 8554, { port: console_port });
|
|
@@ -136,6 +142,14 @@ export const createServer = (options = {}) => {
|
|
|
136
142
|
.optional()
|
|
137
143
|
.describe('Return a screenshot once the keys are pressed'),
|
|
138
144
|
},
|
|
145
|
+
// A key press can confirm anything the app on screen offers, a delete
|
|
146
|
+
// included.
|
|
147
|
+
annotations: {
|
|
148
|
+
readOnlyHint: false,
|
|
149
|
+
destructiveHint: true,
|
|
150
|
+
idempotentHint: false,
|
|
151
|
+
openWorldHint: false,
|
|
152
|
+
},
|
|
139
153
|
}, async ({ keys, gap_ms, screenshot_after }, { signal }) => {
|
|
140
154
|
try {
|
|
141
155
|
const steps = parseKeys(keys); // a typo fails before any device is touched
|
|
@@ -155,7 +169,7 @@ export const createServer = (options = {}) => {
|
|
|
155
169
|
server.registerTool('screenshot', {
|
|
156
170
|
title: 'Take a screenshot',
|
|
157
171
|
description: 'Returns the current screen of the Vega Virtual Device as a PNG image (1920x1080).',
|
|
158
|
-
annotations: { readOnlyHint: true },
|
|
172
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
159
173
|
}, async ({ signal }) => {
|
|
160
174
|
try {
|
|
161
175
|
return { content: [await screen(connected(), signal)] };
|
|
@@ -176,7 +190,7 @@ export const createServer = (options = {}) => {
|
|
|
176
190
|
.optional()
|
|
177
191
|
.describe('Default 5000'),
|
|
178
192
|
},
|
|
179
|
-
annotations: { readOnlyHint: true },
|
|
193
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
180
194
|
}, async ({ timeout_ms }, { signal }) => {
|
|
181
195
|
try {
|
|
182
196
|
const d = connected();
|
|
@@ -211,6 +225,13 @@ export const createServer = (options = {}) => {
|
|
|
211
225
|
.optional()
|
|
212
226
|
.describe('Replace an existing file; default false'),
|
|
213
227
|
},
|
|
228
|
+
// Destructive only with overwrite, which replaces an existing file.
|
|
229
|
+
annotations: {
|
|
230
|
+
readOnlyHint: false,
|
|
231
|
+
destructiveHint: true,
|
|
232
|
+
idempotentHint: false,
|
|
233
|
+
openWorldHint: false,
|
|
234
|
+
},
|
|
214
235
|
}, async ({ file, seconds, fps, audio, overwrite }, { signal }) => {
|
|
215
236
|
try {
|
|
216
237
|
const path = videoPath(file, overwrite);
|
|
@@ -243,7 +264,7 @@ export const createServer = (options = {}) => {
|
|
|
243
264
|
.optional()
|
|
244
265
|
.describe('Fraction of each edge, default 0.05'),
|
|
245
266
|
},
|
|
246
|
-
annotations: { readOnlyHint: true },
|
|
267
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
247
268
|
}, async ({ background, margin }, { signal }) => {
|
|
248
269
|
try {
|
|
249
270
|
const frame = await connected().screenshot('rgb', { signal });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fortemate/vega-vvd-driver",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Unofficial driver for the Vega Virtual Device: remote keys, screenshots and video with sound, from scripts and AI agents. CLI, Node library and MCP server.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vega",
|