@geometra/mcp 1.19.4 → 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 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 `role=option` (React Select, Headless UI, etc.; `@geometra/proxy` only) |
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.4' }, { capabilities: { tools: {} } });
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 visible \`role=option\` (Headless UI, React Select, Radix, etc.). Requires \`@geometra/proxy\`.
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
- Optional openX,openY clicks the combobox first if the list is not open. Uses substring name match unless exact=true.`, {
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
- }, async ({ label, exact, openX, openY }) => {
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.4",
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.4",
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"