@geometra/mcp 1.19.5 → 1.19.6
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 +1 -1
- package/dist/server.js +8 -4
- package/dist/session.d.ts +3 -1
- package/dist/session.js +8 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Geometra proxy: Chromium → DOM geometry → same WebSocket as native →
|
|
|
26
26
|
| `geometra_type` | Type text into the focused element |
|
|
27
27
|
| `geometra_key` | Send special keys (Enter, Tab, Escape, arrows) |
|
|
28
28
|
| `geometra_upload_files` | Attach files: auto / hidden input / native chooser / synthetic drop (`@geometra/proxy` only) |
|
|
29
|
-
| `geometra_pick_listbox_option` | Pick
|
|
29
|
+
| `geometra_pick_listbox_option` | Pick an option from a custom dropdown/searchable combobox; can open by field label (`@geometra/proxy` only) |
|
|
30
30
|
| `geometra_select_option` | Choose an option on a native `<select>` (`@geometra/proxy` only) |
|
|
31
31
|
| `geometra_set_checked` | Set a checkbox or radio by label instead of coordinate clicks (`@geometra/proxy` only) |
|
|
32
32
|
| `geometra_wheel` | Mouse wheel / scroll (`@geometra/proxy` only) |
|
package/dist/server.js
CHANGED
|
@@ -3,7 +3,7 @@ import { z } from 'zod';
|
|
|
3
3
|
import { formatConnectFailureMessage, isHttpUrl, normalizeConnectTarget } from './connect-utils.js';
|
|
4
4
|
import { connect, connectThroughProxy, disconnect, getSession, sendClick, sendType, sendKey, sendFileUpload, sendListboxPick, sendSelectOption, sendSetChecked, sendWheel, buildA11yTree, buildCompactUiIndex, buildPageModel, expandPageSection, buildUiDelta, hasUiDelta, nodeIdForPath, summarizeCompactIndex, summarizePageModel, summarizeUiDelta, } from './session.js';
|
|
5
5
|
export function createServer() {
|
|
6
|
-
const server = new McpServer({ name: 'geometra', version: '1.19.
|
|
6
|
+
const server = new McpServer({ name: 'geometra', version: '1.19.6' }, { capabilities: { tools: {} } });
|
|
7
7
|
// ── connect ──────────────────────────────────────────────────
|
|
8
8
|
server.tool('geometra_connect', `Connect to a Geometra WebSocket peer, or start \`geometra-proxy\` automatically for a normal web page.
|
|
9
9
|
|
|
@@ -221,14 +221,16 @@ Strategies: **auto** (default) tries chooser click if x,y given, else hidden \`i
|
|
|
221
221
|
return err(e.message);
|
|
222
222
|
}
|
|
223
223
|
});
|
|
224
|
-
server.tool('geometra_pick_listbox_option', `Pick a
|
|
224
|
+
server.tool('geometra_pick_listbox_option', `Pick an option from a custom dropdown / listbox / searchable combobox (Headless UI, React Select, Radix, Ashby-style custom selects, etc.). Requires \`@geometra/proxy\`.
|
|
225
225
|
|
|
226
|
-
|
|
226
|
+
Pass \`fieldLabel\` to open a labeled dropdown semantically instead of relying on coordinates. If the opened control is editable, MCP types \`query\` (or the option label by default) before selecting. Uses substring name match unless exact=true.`, {
|
|
227
227
|
label: z.string().describe('Accessible name of the option (visible text or aria-label)'),
|
|
228
228
|
exact: z.boolean().optional().describe('Exact name match'),
|
|
229
229
|
openX: z.number().optional().describe('Click to open dropdown'),
|
|
230
230
|
openY: z.number().optional().describe('Click to open dropdown'),
|
|
231
|
-
|
|
231
|
+
fieldLabel: z.string().optional().describe('Field label of the dropdown/combobox to open semantically (e.g. "Location")'),
|
|
232
|
+
query: z.string().optional().describe('Optional text to type into a searchable combobox before selecting'),
|
|
233
|
+
}, async ({ label, exact, openX, openY, fieldLabel, query }) => {
|
|
232
234
|
const session = getSession();
|
|
233
235
|
if (!session)
|
|
234
236
|
return err('Not connected. Call geometra_connect first.');
|
|
@@ -237,6 +239,8 @@ Optional openX,openY clicks the combobox first if the list is not open. Uses sub
|
|
|
237
239
|
const wait = await sendListboxPick(session, label, {
|
|
238
240
|
exact,
|
|
239
241
|
open: openX !== undefined && openY !== undefined ? { x: openX, y: openY } : undefined,
|
|
242
|
+
fieldLabel,
|
|
243
|
+
query,
|
|
240
244
|
});
|
|
241
245
|
const summary = postActionSummary(session, before, wait);
|
|
242
246
|
return ok(`Picked listbox option "${label}".\n${summary}`);
|
package/dist/session.d.ts
CHANGED
|
@@ -197,7 +197,7 @@ export interface Session {
|
|
|
197
197
|
proxyChild?: ChildProcess;
|
|
198
198
|
}
|
|
199
199
|
export interface UpdateWaitResult {
|
|
200
|
-
status: 'updated' | 'timed_out';
|
|
200
|
+
status: 'updated' | 'acknowledged' | 'timed_out';
|
|
201
201
|
timeoutMs: number;
|
|
202
202
|
}
|
|
203
203
|
/**
|
|
@@ -258,6 +258,8 @@ export declare function sendListboxPick(session: Session, label: string, opts?:
|
|
|
258
258
|
x: number;
|
|
259
259
|
y: number;
|
|
260
260
|
};
|
|
261
|
+
fieldLabel?: string;
|
|
262
|
+
query?: string;
|
|
261
263
|
}): Promise<UpdateWaitResult>;
|
|
262
264
|
/** Native `<select>` only: click the control center, then pick by value, label text, or zero-based index. */
|
|
263
265
|
export declare function sendSelectOption(session: Session, x: number, y: number, option: {
|
package/dist/session.js
CHANGED
|
@@ -204,6 +204,10 @@ export function sendListboxPick(session, label, opts) {
|
|
|
204
204
|
payload.openX = opts.open.x;
|
|
205
205
|
payload.openY = opts.open.y;
|
|
206
206
|
}
|
|
207
|
+
if (opts?.fieldLabel)
|
|
208
|
+
payload.fieldLabel = opts.fieldLabel;
|
|
209
|
+
if (opts?.query)
|
|
210
|
+
payload.query = opts.query;
|
|
207
211
|
return sendAndWaitForUpdate(session, payload);
|
|
208
212
|
}
|
|
209
213
|
/** Native `<select>` only: click the control center, then pick by value, label text, or zero-based index. */
|
|
@@ -1158,6 +1162,10 @@ function waitForNextUpdate(session) {
|
|
|
1158
1162
|
cleanup();
|
|
1159
1163
|
resolve({ status: 'updated', timeoutMs: ACTION_UPDATE_TIMEOUT_MS });
|
|
1160
1164
|
}
|
|
1165
|
+
else if (msg.type === 'ack') {
|
|
1166
|
+
cleanup();
|
|
1167
|
+
resolve({ status: 'acknowledged', timeoutMs: ACTION_UPDATE_TIMEOUT_MS });
|
|
1168
|
+
}
|
|
1161
1169
|
}
|
|
1162
1170
|
catch { /* ignore */ }
|
|
1163
1171
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geometra/mcp",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.6",
|
|
4
4
|
"description": "MCP server for Geometra — interact with running Geometra apps via the geometry protocol, no browser needed",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ui-testing"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@geometra/proxy": "1.19.
|
|
33
|
+
"@geometra/proxy": "1.19.6",
|
|
34
34
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
35
35
|
"ws": "^8.18.0",
|
|
36
36
|
"zod": "^3.23.0"
|