openinputbridge-mcp 0.1.0

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/dist/tools.js ADDED
@@ -0,0 +1,465 @@
1
+ /**
2
+ * MCP tool surface (v1, send-only). Registers every tool onto the given
3
+ * McpServer. See the project plan for the rationale behind the tool list
4
+ * and the arm/rate-limit safety gate.
5
+ */
6
+ import { z } from "zod";
7
+ import { OibBridgeError } from "./bridge.js";
8
+ import { NotArmedError, RateLimitError } from "./safety.js";
9
+ import { KEY_TABLE, MODIFIER_KEYS, charToKeyEvent, LANGID_TO_AUTO_LAYOUT, } from "./keycodes.js";
10
+ const KEY_NAMES = Object.keys(KEY_TABLE);
11
+ const LAYOUT_IDS = ["us", "jis", "de", "fr", "ru", "ko", "tw"];
12
+ /*
13
+ * The keyboard/mouse slot boundary is admin-configurable at driver install
14
+ * time (KeyboardSlotCount), not fixed at 10/10 - see docs/PROTOCOL.md and
15
+ * helper/oib_bridge.c's EnsureKeyboardSlotCount(). These schemas only
16
+ * enforce the outer 0-19 device range; the helper checks the real
17
+ * (queried) boundary and rejects a keyboard call routed at a mouse slot
18
+ * or vice versa. Callers who need a non-default slot should look at
19
+ * get_driver_status's keyboardSlotCount/mouseSlotCount fields first.
20
+ */
21
+ const KEYBOARD_DEVICE_SCHEMA = z
22
+ .number()
23
+ .int()
24
+ .min(0)
25
+ .max(19)
26
+ .default(0)
27
+ .describe("Keyboard slot index. Defaults to 0 (always a keyboard slot). The keyboard/mouse boundary is " +
28
+ "admin-configurable - check get_driver_status's keyboardSlotCount if targeting a specific slot.");
29
+ const MOUSE_DEVICE_SCHEMA = z
30
+ .number()
31
+ .int()
32
+ .min(0)
33
+ .max(19)
34
+ .default(10)
35
+ .describe("Mouse slot index. Defaults to 10 (the first mouse slot under the default 10/10 split). The keyboard/mouse " +
36
+ "boundary is admin-configurable - check get_driver_status's keyboardSlotCount/mouseSlotCount first if unsure.");
37
+ const TAP_HOLD_MS = 25;
38
+ /**
39
+ * Minimum gap enforced after every individual key/modifier transition
40
+ * (not just within a tap). Confirmed necessary by real-hardware testing:
41
+ * our own DeviceIoControl calls are strictly sequential and each
42
+ * synchronous down to the class driver hand-off, but the OS's downstream
43
+ * raw-input pipeline (kbdclass -> raw input thread -> TranslateMessage/
44
+ * ToUnicode's modifier-state lookup -> WM_CHAR delivery) processes events
45
+ * asynchronously relative to that; firing events back to back with no gap
46
+ * measurably dropped characters on real hardware even though every
47
+ * IOCTL_WRITE call succeeded. This alone was not enough to fix rapid
48
+ * same-scancode modifier repeats though (see the ShiftLeft/ShiftRight
49
+ * alternation in type_text below) - see test/REALWORLD_TESTING.md.
50
+ */
51
+ const KEY_EVENT_SETTLE_MS = 30;
52
+ /**
53
+ * Minimum gap enforced after every mouse event (move/click/wheel), for the
54
+ * same reason as KEY_EVENT_SETTLE_MS: our IOCTL_WRITE call returning
55
+ * successfully only means mouclass accepted the record, not that the OS
56
+ * has finished propagating it to the actual on-screen cursor position.
57
+ * Confirmed on real hardware: reading back the cursor position (or
58
+ * clicking) immediately after an absolute mouse_move landed on a stale/
59
+ * transient position around half the time; waiting even briefly first
60
+ * made every read match the expected coordinate. See
61
+ * test/REALWORLD_TESTING.md.
62
+ */
63
+ const MOUSE_EVENT_SETTLE_MS = 50;
64
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
65
+ function textResult(text, isError = false) {
66
+ return { content: [{ type: "text", text }], isError };
67
+ }
68
+ function errorResult(err) {
69
+ if (err instanceof NotArmedError || err instanceof RateLimitError) {
70
+ return textResult(err.message, true);
71
+ }
72
+ if (err instanceof OibBridgeError) {
73
+ return textResult(`OpenInputBridge error: ${err.message}`, true);
74
+ }
75
+ const message = err instanceof Error ? err.message : String(err);
76
+ return textResult(`Unexpected error: ${message}`, true);
77
+ }
78
+ const MOUSE_BUTTON_FLAGS = {
79
+ left: { down: 0x0001, up: 0x0002 },
80
+ right: { down: 0x0004, up: 0x0008 },
81
+ middle: { down: 0x0010, up: 0x0020 },
82
+ x1: { down: 0x0040, up: 0x0080 },
83
+ x2: { down: 0x0100, up: 0x0200 },
84
+ };
85
+ async function tapKey(bridge, device, key) {
86
+ const code = KEY_TABLE[key];
87
+ await bridge.writeKey(device, code.makeCode, true, code.extended);
88
+ await sleep(TAP_HOLD_MS);
89
+ await bridge.writeKey(device, code.makeCode, false, code.extended);
90
+ await sleep(KEY_EVENT_SETTLE_MS);
91
+ }
92
+ async function setKeyState(bridge, device, key, down) {
93
+ const code = KEY_TABLE[key];
94
+ await bridge.writeKey(device, code.makeCode, down, code.extended);
95
+ await sleep(KEY_EVENT_SETTLE_MS);
96
+ }
97
+ /**
98
+ * Resolves "auto" to the layout of whatever window currently has focus
99
+ * (queried fresh per call, since the focused app/layout can change
100
+ * between calls). Falls back to "us" if the query fails, or if the
101
+ * detected LANGID isn't one of the auto-detectable layouts (this
102
+ * includes Korean/Taiwan - see LANGID_TO_AUTO_LAYOUT's doc comment for
103
+ * why those are explicit-only). Only affects which characters
104
+ * type_text can produce, never press_key/key_down/key_up (those name a
105
+ * physical key, not a character).
106
+ */
107
+ async function resolveTypeTextLayout(bridge, requested) {
108
+ if (requested !== "auto")
109
+ return requested;
110
+ try {
111
+ const languageId = await bridge.getActiveKeyboardLayout();
112
+ return LANGID_TO_AUTO_LAYOUT.get(languageId) ?? "us";
113
+ }
114
+ catch {
115
+ return "us";
116
+ }
117
+ }
118
+ export function registerTools(server, bridge, safety) {
119
+ server.registerTool("enable_input_control", {
120
+ title: "Enable input control",
121
+ description: "Arms the session for synthetic key/mouse input. Must be called once before any of press_key, " +
122
+ "key_down, key_up, type_text, mouse_move, mouse_click, or mouse_wheel will work. This is a deliberate " +
123
+ "extra confirmation step, separate from the MCP client's own tool-permission UI, given how powerful " +
124
+ "unattended input injection is.",
125
+ inputSchema: {},
126
+ }, async () => {
127
+ safety.arm();
128
+ return textResult("Input control armed. Synthetic key/mouse tools are now enabled for this session.");
129
+ });
130
+ server.registerTool("disable_input_control", {
131
+ title: "Disable input control",
132
+ description: "Disarms the session. All synthetic input tools will be rejected until enable_input_control is called again.",
133
+ inputSchema: {},
134
+ }, async () => {
135
+ safety.disarm();
136
+ return textResult("Input control disarmed.");
137
+ });
138
+ server.registerTool("get_driver_status", {
139
+ title: "Get OpenInputBridge driver status",
140
+ description: "Diagnostic tool: checks whether the OpenInputBridge driver is installed and running, and returns its " +
141
+ "version. Does not require enable_input_control (it sends no input). Call this first if other tools fail.",
142
+ inputSchema: {},
143
+ }, async () => {
144
+ try {
145
+ const status = await bridge.status();
146
+ return textResult(JSON.stringify(status));
147
+ }
148
+ catch (err) {
149
+ const message = err instanceof Error ? err.message : String(err);
150
+ return textResult(JSON.stringify({ installed: false, error: message }));
151
+ }
152
+ });
153
+ server.registerTool("press_key", {
154
+ title: "Press a key (tap)",
155
+ description: "Presses and releases a single key, optionally held with modifiers (e.g. key='KeyA', modifiers=['ControlLeft'] " +
156
+ "for Ctrl+A). Key names follow the DOM KeyboardEvent.code vocabulary (KeyA-KeyZ, Digit0-Digit9, Enter, " +
157
+ "ArrowUp, F1-F12, etc.). US QWERTY layout only.",
158
+ inputSchema: {
159
+ key: z.enum(KEY_NAMES).describe("Physical key to press, e.g. 'KeyA', 'Enter', 'F5', 'ArrowLeft'."),
160
+ modifiers: z
161
+ .array(z.enum(MODIFIER_KEYS))
162
+ .default([])
163
+ .describe("Modifier keys to hold down for the duration of the tap, e.g. ['ControlLeft', 'ShiftLeft']."),
164
+ device: KEYBOARD_DEVICE_SCHEMA,
165
+ },
166
+ }, async ({ key, modifiers, device }) => {
167
+ try {
168
+ safety.checkAndConsume((modifiers.length + 1) * 2);
169
+ for (const mod of modifiers) {
170
+ await setKeyState(bridge, device, mod, true);
171
+ }
172
+ await tapKey(bridge, device, key);
173
+ for (const mod of [...modifiers].reverse()) {
174
+ await setKeyState(bridge, device, mod, false);
175
+ }
176
+ return textResult(`Pressed ${modifiers.length ? modifiers.join("+") + "+" : ""}${key}.`);
177
+ }
178
+ catch (err) {
179
+ return errorResult(err);
180
+ }
181
+ });
182
+ server.registerTool("key_down", {
183
+ title: "Hold a key down",
184
+ description: "Presses a key without releasing it. Pair with key_up for composite gestures (e.g. holding Shift while " +
185
+ "clicking). Remember to release every key you hold down.",
186
+ inputSchema: {
187
+ key: z.enum(KEY_NAMES),
188
+ device: KEYBOARD_DEVICE_SCHEMA,
189
+ },
190
+ }, async ({ key, device }) => {
191
+ try {
192
+ safety.checkAndConsume(1);
193
+ await setKeyState(bridge, device, key, true);
194
+ return textResult(`${key} is now held down.`);
195
+ }
196
+ catch (err) {
197
+ return errorResult(err);
198
+ }
199
+ });
200
+ server.registerTool("key_up", {
201
+ title: "Release a held key",
202
+ description: "Releases a key previously pressed with key_down.",
203
+ inputSchema: {
204
+ key: z.enum(KEY_NAMES),
205
+ device: KEYBOARD_DEVICE_SCHEMA,
206
+ },
207
+ }, async ({ key, device }) => {
208
+ try {
209
+ safety.checkAndConsume(1);
210
+ await setKeyState(bridge, device, key, false);
211
+ return textResult(`${key} released.`);
212
+ }
213
+ catch (err) {
214
+ return errorResult(err);
215
+ }
216
+ });
217
+ server.registerTool("type_text", {
218
+ title: "Type a text string",
219
+ description: "Types a string as a sequence of keystrokes (no IME/kanji-hangul-hanzi conversion support - direct " +
220
+ "alphanumeric/symbol/jamo/zhuyin entry only, see the `layout` parameter). Supports letters, digits, " +
221
+ "common punctuation, space, tab, and newline (sent as Enter). Which physical key + Shift state " +
222
+ "produces a given character depends on the active keyboard layout of whatever window has focus " +
223
+ "(layout='auto', the default, detects this per call for us/jis/de/fr/ru). The whole string is " +
224
+ "validated before anything is sent, so a call either types in full or is rejected with no partial " +
225
+ "side effects.",
226
+ inputSchema: {
227
+ text: z.string().min(1).max(4000),
228
+ layout: z
229
+ .enum(["auto", ...LAYOUT_IDS])
230
+ .default("auto")
231
+ .describe("Keyboard layout used to map characters to physical keys. 'auto' (default) detects the active " +
232
+ "layout of the focused window per call, choosing between us/jis/de/fr/ru (plain letters/digits " +
233
+ "are unaffected by layout choice; only symbols and, for jis/de/fr/ru, some letters differ). " +
234
+ "'ko' (Korean 2-beolsik) and 'tw' (Taiwan Zhuyin/Bopomofo) must be requested explicitly - they " +
235
+ "are never auto-detected, and produce uncomposed jamo/zhuyin symbols only (no IME syllable/" +
236
+ "Han-character composition - e.g. 'r'+'k' on layout='ko' sends the two separate jamo characters " +
237
+ "'ㄱ' and 'ㅏ', not the composed syllable '가'). de/fr/ru/ko/tw are unverified against real " +
238
+ "hardware, unlike us/jis - see test/REALWORLD_TESTING.md."),
239
+ delayMs: z
240
+ .number()
241
+ .int()
242
+ .min(0)
243
+ .max(1000)
244
+ .default(20)
245
+ .describe("Delay in milliseconds between characters, to mimic natural typing pace."),
246
+ device: KEYBOARD_DEVICE_SCHEMA,
247
+ },
248
+ }, async ({ text, layout: layoutParam, delayMs, device, }) => {
249
+ const layout = await resolveTypeTextLayout(bridge, layoutParam);
250
+ const events = [];
251
+ const unsupported = new Set();
252
+ for (const ch of text) {
253
+ const ev = charToKeyEvent(ch, layout);
254
+ if (!ev) {
255
+ unsupported.add(ch);
256
+ }
257
+ else {
258
+ events.push(ev);
259
+ }
260
+ }
261
+ if (unsupported.size > 0) {
262
+ return textResult(`Cannot type this text with layout='${layout}': unsupported character(s) ` +
263
+ `${[...unsupported].map((c) => JSON.stringify(c)).join(", ")}. Only letters/digits/punctuation ` +
264
+ "supported by that layout, space, tab, and newline are supported.", true);
265
+ }
266
+ try {
267
+ const cost = events.reduce((sum, ev) => sum + (ev.shift ? 4 : 2), 0);
268
+ safety.checkAndConsume(cost);
269
+ // Alternate ShiftLeft/ShiftRight across consecutive shifted
270
+ // characters rather than always reusing ShiftLeft. Confirmed by
271
+ // real-hardware testing: rapidly toggling the *same* scancode
272
+ // down/up/down/up (e.g. every shifted char in "MiXeD") is
273
+ // unreliable - Windows' input pipeline silently drops some of the
274
+ // repeated transitions even with generous settle delays. Using a
275
+ // different physical key each time avoids same-scancode repeat
276
+ // entirely and was reliable even at the tool's normal (non-slowed)
277
+ // timing. See test/REALWORLD_TESTING.md.
278
+ let nextShiftKey = "ShiftLeft";
279
+ for (const ev of events) {
280
+ const shiftKey = nextShiftKey;
281
+ if (ev.shift) {
282
+ await setKeyState(bridge, device, shiftKey, true);
283
+ nextShiftKey = shiftKey === "ShiftLeft" ? "ShiftRight" : "ShiftLeft";
284
+ }
285
+ await tapKey(bridge, device, ev.key);
286
+ if (ev.shift)
287
+ await setKeyState(bridge, device, shiftKey, false);
288
+ if (delayMs > 0)
289
+ await sleep(delayMs);
290
+ }
291
+ return textResult(`Typed ${events.length} character(s) (layout: ${layout}).`);
292
+ }
293
+ catch (err) {
294
+ return errorResult(err);
295
+ }
296
+ });
297
+ server.registerTool("mouse_move", {
298
+ title: "Move the mouse",
299
+ description: "Moves the mouse, either relative to its current position (default) or to absolute coordinates " +
300
+ "(same semantics as a raw MOUSE_INPUT_DATA record with MOUSE_MOVE_ABSOLUTE). Absolute coordinates are " +
301
+ "normalized 0-65535 and map to the primary monitor's pixel bounds by default (same convention as " +
302
+ "SendInput's MOUSEEVENTF_ABSOLUTE) - set virtualDesktop=true to map them across the full virtual " +
303
+ "desktop (all monitors combined) instead, to reach secondary monitors directly.",
304
+ inputSchema: {
305
+ x: z.number().int(),
306
+ y: z.number().int(),
307
+ absolute: z.boolean().default(false),
308
+ virtualDesktop: z
309
+ .boolean()
310
+ .default(false)
311
+ .describe("Only meaningful when absolute=true: normalize x/y against the full virtual desktop bounds " +
312
+ "(all monitors) instead of just the primary monitor, letting absolute coordinates reach secondary " +
313
+ "monitors. Ignored when absolute=false."),
314
+ device: MOUSE_DEVICE_SCHEMA,
315
+ },
316
+ }, async ({ x, y, absolute, virtualDesktop, device, }) => {
317
+ try {
318
+ safety.checkAndConsume(1);
319
+ await bridge.writeMouseMove(device, x, y, absolute, virtualDesktop);
320
+ if (absolute) {
321
+ // Confirmed on real hardware: the *first* absolute MOUSE_INPUT_DATA
322
+ // write after any non-absolute mouse activity, or after a change
323
+ // in which Flags bits are combined (e.g. adding/removing
324
+ // MOUSE_VIRTUAL_DESKTOP), is silently ignored or lands on a stale
325
+ // position - but repeating the same write settles it. Two repeats
326
+ // (three writes total) reliably converged in testing where a
327
+ // single repeat (two total) sometimes did not, particularly right
328
+ // after switching virtualDesktop on/off. This looks like the same
329
+ // "first sample only calibrates" behavior common to real absolute
330
+ // pointing devices (touchscreens/tablets). Repeating is harmless -
331
+ // a no-op resend of an already-applied move has no visible effect.
332
+ // See test/REALWORLD_TESTING.md item 6.
333
+ await sleep(MOUSE_EVENT_SETTLE_MS);
334
+ await bridge.writeMouseMove(device, x, y, absolute, virtualDesktop);
335
+ await sleep(MOUSE_EVENT_SETTLE_MS);
336
+ await bridge.writeMouseMove(device, x, y, absolute, virtualDesktop);
337
+ }
338
+ await sleep(MOUSE_EVENT_SETTLE_MS);
339
+ return textResult(`Moved mouse ${absolute ? "to" : "by"} (${x}, ${y})${absolute && virtualDesktop ? " (virtual desktop)" : ""}.`);
340
+ }
341
+ catch (err) {
342
+ return errorResult(err);
343
+ }
344
+ });
345
+ server.registerTool("mouse_click", {
346
+ title: "Click a mouse button",
347
+ description: "Clicks (or presses/releases) a mouse button: left, right, middle, x1 (back), or x2 (forward).",
348
+ inputSchema: {
349
+ button: z.enum(["left", "right", "middle", "x1", "x2"]),
350
+ action: z.enum(["click", "down", "up"]).default("click"),
351
+ device: MOUSE_DEVICE_SCHEMA,
352
+ },
353
+ }, async ({ button, action, device, }) => {
354
+ try {
355
+ const flags = MOUSE_BUTTON_FLAGS[button];
356
+ safety.checkAndConsume(action === "click" ? 2 : 1);
357
+ if (action === "click") {
358
+ await bridge.writeMouseButton(device, flags.down);
359
+ await sleep(TAP_HOLD_MS);
360
+ await bridge.writeMouseButton(device, flags.up);
361
+ }
362
+ else if (action === "down") {
363
+ await bridge.writeMouseButton(device, flags.down);
364
+ }
365
+ else {
366
+ await bridge.writeMouseButton(device, flags.up);
367
+ }
368
+ await sleep(MOUSE_EVENT_SETTLE_MS);
369
+ return textResult(`${button} button: ${action}.`);
370
+ }
371
+ catch (err) {
372
+ return errorResult(err);
373
+ }
374
+ });
375
+ server.registerTool("mouse_wheel", {
376
+ title: "Scroll the mouse wheel",
377
+ description: "Scrolls the vertical (default) or horizontal wheel. Delta is in the same units as Windows wheel " +
378
+ "messages, where +/-120 is one notch.",
379
+ inputSchema: {
380
+ delta: z.number().int().min(-32768).max(32767).describe("Positive scrolls up/right, negative scrolls down/left. +/-120 = one notch."),
381
+ horizontal: z.boolean().default(false),
382
+ device: MOUSE_DEVICE_SCHEMA,
383
+ },
384
+ }, async ({ delta, horizontal, device }) => {
385
+ try {
386
+ safety.checkAndConsume(1);
387
+ await bridge.writeMouseWheel(device, delta, horizontal);
388
+ await sleep(MOUSE_EVENT_SETTLE_MS);
389
+ return textResult(`Scrolled ${horizontal ? "horizontal" : "vertical"} wheel by ${delta}.`);
390
+ }
391
+ catch (err) {
392
+ return errorResult(err);
393
+ }
394
+ });
395
+ server.registerTool("enable_exclusive_input_mode", {
396
+ title: "Enable exclusive input mode",
397
+ description: "TESTING/CI USE ONLY - this makes the physical keyboard and mouse stop working for the whole machine. " +
398
+ "Captures every physical key/mouse event on every slot and discards it, so only this MCP session's own " +
399
+ "tool calls (press_key, mouse_move, etc.) reach the target application - useful for deterministic test " +
400
+ "runs where an operator's stray physical input would otherwise flake the test. Requires " +
401
+ "enable_input_control to have been called first. A background watchdog auto-disables this if the MCP " +
402
+ "server stops sending heartbeats for watchdogTimeoutMs, and the OS itself restores physical input the " +
403
+ "instant this process exits for any reason (crash, kill, normal shutdown) - killing the oib_bridge.exe " +
404
+ "process is always a working manual escape hatch, even if this MCP server is unresponsive. Secure " +
405
+ "attention sequences (Ctrl+Alt+Del) are handled by Windows below this driver and are not affected.",
406
+ inputSchema: {
407
+ watchdogTimeoutMs: z
408
+ .number()
409
+ .int()
410
+ .min(1000)
411
+ .max(300000)
412
+ .default(5000)
413
+ .describe("Auto-disable if no heartbeat is received for this many milliseconds (1000-300000, default 5000)."),
414
+ },
415
+ }, async ({ watchdogTimeoutMs }) => {
416
+ try {
417
+ safety.checkAndConsume(1);
418
+ const info = await bridge.enableExclusiveMode(watchdogTimeoutMs);
419
+ return textResult(`Exclusive input mode enabled. Physical input is now captured and discarded on all ` +
420
+ `${info.keyboardSlotCount} keyboard + ${info.mouseSlotCount} mouse slot(s); only this session's ` +
421
+ `synthetic input reaches the target application. Watchdog timeout: ${info.watchdogTimeoutMs}ms. ` +
422
+ `Call disable_exclusive_input_mode to restore physical input.`);
423
+ }
424
+ catch (err) {
425
+ return errorResult(err);
426
+ }
427
+ });
428
+ server.registerTool("disable_exclusive_input_mode", {
429
+ title: "Disable exclusive input mode",
430
+ description: "Restores physical keyboard/mouse input. Safe to call any time, including when exclusive mode is " +
431
+ "already off, and deliberately bypasses the arm/rate-limit gate so it always works as an escape hatch.",
432
+ inputSchema: {},
433
+ }, async () => {
434
+ try {
435
+ const result = await bridge.disableExclusiveMode();
436
+ if (!result.wasActive) {
437
+ return textResult("Exclusive input mode was already off.");
438
+ }
439
+ const warning = result.failedDeviceCount > 0
440
+ ? ` Warning: ${result.failedDeviceCount} device(s) failed to reset - if physical input still seems ` +
441
+ "unresponsive, kill the oib_bridge.exe process (this always restores it)."
442
+ : "";
443
+ return textResult(`Exclusive input mode disabled; physical input restored.${warning}`, result.failedDeviceCount > 0);
444
+ }
445
+ catch (err) {
446
+ return errorResult(err);
447
+ }
448
+ });
449
+ server.registerTool("get_exclusive_mode_status", {
450
+ title: "Get exclusive input mode status",
451
+ description: "Reports whether exclusive input mode is currently active (authoritative, queried live from the " +
452
+ "helper process). Does not require enable_input_control. Note: calling this also refreshes the " +
453
+ "watchdog heartbeat, same as the automatic background heartbeat does.",
454
+ inputSchema: {},
455
+ }, async () => {
456
+ try {
457
+ const active = await bridge.heartbeat();
458
+ return textResult(JSON.stringify({ exclusiveModeActive: active }));
459
+ }
460
+ catch (err) {
461
+ return errorResult(err);
462
+ }
463
+ });
464
+ }
465
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "openinputbridge-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server exposing OpenInputBridge (Interception-compatible kernel-level input) as SendInput()-alternative tools for GUI/native-app test automation.",
5
+ "license": "MIT",
6
+ "author": "Applet-LLC",
7
+ "homepage": "https://github.com/Applet-LLC/OpenInputBridge-MCP#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Applet-LLC/OpenInputBridge-MCP.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/Applet-LLC/OpenInputBridge-MCP/issues"
14
+ },
15
+ "keywords": [
16
+ "mcp",
17
+ "model-context-protocol",
18
+ "windows",
19
+ "automation",
20
+ "testing",
21
+ "keyboard",
22
+ "mouse",
23
+ "sendinput",
24
+ "interception",
25
+ "claude"
26
+ ],
27
+ "os": ["win32"],
28
+ "type": "module",
29
+ "bin": {
30
+ "openinputbridge-mcp": "dist/index.js"
31
+ },
32
+ "main": "dist/index.js",
33
+ "files": [
34
+ "dist",
35
+ "bin"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsc -p tsconfig.json",
39
+ "dev": "tsc -p tsconfig.json --watch",
40
+ "start": "node dist/index.js",
41
+ "prepublishOnly": "node scripts/check-native-binary.mjs"
42
+ },
43
+ "dependencies": {
44
+ "@modelcontextprotocol/sdk": "^1.0.0",
45
+ "zod": "^3.23.8"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.0.0",
49
+ "typescript": "^5.6.0"
50
+ },
51
+ "engines": {
52
+ "node": ">=18"
53
+ }
54
+ }