safari-mcp 2.7.10 → 2.7.11
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/index.js +13 -0
- package/package.json +1 -1
- package/safari.js +38 -0
package/index.js
CHANGED
|
@@ -1009,6 +1009,19 @@ server.tool(
|
|
|
1009
1009
|
}
|
|
1010
1010
|
);
|
|
1011
1011
|
|
|
1012
|
+
server.tool(
|
|
1013
|
+
"safari_native_keyboard",
|
|
1014
|
+
"OS-level keyboard event via macOS CGEvent — sends a real keypress (with optional modifiers) to the Safari window WITHOUT activating Safari or stealing focus. Use when safari_press_key's JS path doesn't reach React trust-gated handlers (Discord ProseMirror Enter, Slack send, virtualized editors). Keys: enter, return, tab, escape, space, delete, backspace, up/down/left/right, home, end, pageup, pagedown, f1-f6, a-z, 0-9 and common punctuation. Modifiers: cmd, shift, alt, ctrl. Produces isTrusted:true events. Never activates Safari — runs entirely in the background.",
|
|
1015
|
+
{
|
|
1016
|
+
key: z.string().describe("Key name: enter, escape, tab, space, arrow keys, letters, digits, etc."),
|
|
1017
|
+
modifiers: z.array(z.string()).optional().default([]).describe("Modifier keys: cmd, shift, alt, ctrl"),
|
|
1018
|
+
},
|
|
1019
|
+
async (args) => {
|
|
1020
|
+
const result = await safari.nativeKeyboard(args);
|
|
1021
|
+
return { content: [{ type: "text", text: typeof result === 'string' ? result : JSON.stringify(result) }] };
|
|
1022
|
+
}
|
|
1023
|
+
);
|
|
1024
|
+
|
|
1012
1025
|
// ========== FORM INPUT ==========
|
|
1013
1026
|
|
|
1014
1027
|
server.tool(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "safari-mcp",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.11",
|
|
4
4
|
"mcpName": "io.github.achiya-automation/safari-mcp",
|
|
5
5
|
"description": "Safari browser automation for AI agents — native macOS, zero Chrome overhead. 80 tools via AppleScript + JavaScript.",
|
|
6
6
|
"type": "module",
|
package/safari.js
CHANGED
|
@@ -1397,6 +1397,44 @@ const jsKeyMap = {
|
|
|
1397
1397
|
f1: "F1", f2: "F2", f3: "F3", f4: "F4", f5: "F5", f6: "F6",
|
|
1398
1398
|
};
|
|
1399
1399
|
|
|
1400
|
+
// macOS virtual key codes for CGEvent keyboard (used by _helperNativeKeyboard).
|
|
1401
|
+
// These are the HID-level codes that postToPid uses, NOT JS keyCode values.
|
|
1402
|
+
const macKeyCodeMap = {
|
|
1403
|
+
enter: 36, return: 36, "numpad-enter": 76,
|
|
1404
|
+
tab: 48, space: 49, delete: 51, backspace: 51, escape: 53,
|
|
1405
|
+
up: 126, "arrowup": 126, down: 125, "arrowdown": 125,
|
|
1406
|
+
left: 123, "arrowleft": 123, right: 124, "arrowright": 124,
|
|
1407
|
+
home: 115, end: 119, pageup: 116, pagedown: 121,
|
|
1408
|
+
f1: 122, f2: 120, f3: 99, f4: 118, f5: 96, f6: 97,
|
|
1409
|
+
a: 0, s: 1, d: 2, f: 3, h: 4, g: 5, z: 6, x: 7, c: 8, v: 9,
|
|
1410
|
+
b: 11, q: 12, w: 13, e: 14, r: 15, y: 16, t: 17,
|
|
1411
|
+
"1": 18, "2": 19, "3": 20, "4": 21, "6": 22, "5": 23,
|
|
1412
|
+
"=": 24, "9": 25, "7": 26, "-": 27, "8": 28, "0": 29,
|
|
1413
|
+
"]": 30, o: 31, u: 32, "[": 33, i: 34, p: 35,
|
|
1414
|
+
l: 37, j: 38, "'": 39, k: 40, ";": 41, "\\": 42,
|
|
1415
|
+
",": 43, "/": 44, n: 45, m: 46, ".": 47, "`": 50,
|
|
1416
|
+
};
|
|
1417
|
+
|
|
1418
|
+
// Native keyboard via CGEvent — sends a single key (with optional modifiers)
|
|
1419
|
+
// to the Safari window WITHOUT activating Safari or moving the mouse.
|
|
1420
|
+
// This produces isTrusted:true events that bypass React trust checks (Discord ProseMirror,
|
|
1421
|
+
// Slack virtualized editors, etc.) without any focus stealing. Requires Safari window ID.
|
|
1422
|
+
export async function nativeKeyboard({ key, modifiers = [] }) {
|
|
1423
|
+
await ensureHelpers();
|
|
1424
|
+
if (!key) throw new Error("nativeKeyboard requires 'key'");
|
|
1425
|
+
const k = String(key).toLowerCase();
|
|
1426
|
+
const keyCode = macKeyCodeMap[k];
|
|
1427
|
+
if (keyCode === undefined) {
|
|
1428
|
+
throw new Error(`nativeKeyboard: unsupported key "${key}". Supported: ${Object.keys(macKeyCodeMap).join(", ")}`);
|
|
1429
|
+
}
|
|
1430
|
+
const geo = await _getSafariWindowGeometry();
|
|
1431
|
+
if (!geo.windowId) throw new Error("Cannot native-key without Safari window ID — would steal focus");
|
|
1432
|
+
const normalized = (modifiers || []).map(m => String(m).toLowerCase());
|
|
1433
|
+
await _helperNativeKeyboard(keyCode, normalized, geo.windowId);
|
|
1434
|
+
const modsLabel = normalized.length ? normalized.join("+") + "+" : "";
|
|
1435
|
+
return `Native key: ${modsLabel}${k} (CGEvent to window ${geo.windowId}, no focus steal)`;
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1400
1438
|
// System Events key codes — only used for paste_image, upload_file, save_pdf
|
|
1401
1439
|
// (functions that truly require OS-level UI interaction)
|
|
1402
1440
|
|