@beeos-ai/device-mcp-server 0.3.0 → 0.4.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.
Files changed (56) hide show
  1. package/dist/backends/android-adb.d.ts +147 -6
  2. package/dist/backends/android-adb.js +776 -40
  3. package/dist/backends/android-adb.js.map +1 -1
  4. package/dist/backends/base.d.ts +243 -7
  5. package/dist/backends/base.js +81 -2
  6. package/dist/backends/base.js.map +1 -1
  7. package/dist/backends/desktop.d.ts +3 -2
  8. package/dist/backends/desktop.js +9 -3
  9. package/dist/backends/desktop.js.map +1 -1
  10. package/dist/backends/linux.js +3 -0
  11. package/dist/backends/linux.js.map +1 -1
  12. package/dist/backends/mac.d.ts +11 -2
  13. package/dist/backends/mac.js +39 -1
  14. package/dist/backends/mac.js.map +1 -1
  15. package/dist/backends/stubs/windows.js +3 -0
  16. package/dist/backends/stubs/windows.js.map +1 -1
  17. package/dist/cli.d.ts +40 -26
  18. package/dist/cli.js +118 -84
  19. package/dist/cli.js.map +1 -1
  20. package/dist/index.d.ts +9 -6
  21. package/dist/index.js +9 -6
  22. package/dist/index.js.map +1 -1
  23. package/dist/server/app.d.ts +60 -17
  24. package/dist/server/app.js +182 -138
  25. package/dist/server/app.js.map +1 -1
  26. package/dist/server/mcp-server.d.ts +25 -0
  27. package/dist/server/mcp-server.js +33 -0
  28. package/dist/server/mcp-server.js.map +1 -0
  29. package/dist/server/registry.d.ts +111 -0
  30. package/dist/server/registry.js +191 -0
  31. package/dist/server/registry.js.map +1 -0
  32. package/dist/server/stdio.d.ts +29 -0
  33. package/dist/server/stdio.js +35 -0
  34. package/dist/server/stdio.js.map +1 -0
  35. package/dist/server/tool-registry.d.ts +60 -35
  36. package/dist/server/tool-registry.js +911 -434
  37. package/dist/server/tool-registry.js.map +1 -1
  38. package/dist/util/adb-files.d.ts +25 -1
  39. package/dist/util/adb-files.js +95 -0
  40. package/dist/util/adb-files.js.map +1 -1
  41. package/dist/util/locale.d.ts +16 -0
  42. package/dist/util/locale.js +31 -0
  43. package/dist/util/locale.js.map +1 -0
  44. package/dist/util/logger.d.ts +27 -0
  45. package/dist/util/logger.js +27 -0
  46. package/dist/util/logger.js.map +1 -0
  47. package/dist/util/output-path.d.ts +60 -0
  48. package/dist/util/output-path.js +123 -0
  49. package/dist/util/output-path.js.map +1 -0
  50. package/dist/util/package-name.d.ts +26 -0
  51. package/dist/util/package-name.js +41 -0
  52. package/dist/util/package-name.js.map +1 -0
  53. package/package.json +5 -3
  54. package/dist/server/action-mapping.d.ts +0 -21
  55. package/dist/server/action-mapping.js +0 -153
  56. package/dist/server/action-mapping.js.map +0 -1
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Android package-name validation.
3
+ *
4
+ * mobile-mcp parity (round 3): mirrors `validatePackageName` from
5
+ * `mobile-mcp/src/utils.ts` — `[a-zA-Z0-9._]` only, with no leading dot
6
+ * relaxation since Android's own package-name grammar (RFC-1034 segments
7
+ * separated by `.`) maps cleanly onto this character class.
8
+ *
9
+ * Used at the MCP tool boundary (`terminate_app`, `uninstall_app`) to fail
10
+ * a malformed input EARLY — before it travels through the runner, gets
11
+ * shell-escaped by `sh\`...\``, and produces a confusing "package not
12
+ * found" error from `pm uninstall`. We deliberately do NOT call this in
13
+ * `launch_app` because that handler accepts user-friendly display names
14
+ * (e.g. "WeChat" -> `com.tencent.mm`) which are mapped to package ids
15
+ * inside the backend.
16
+ */
17
+ import { DeviceError } from "@beeos-ai/device-common";
18
+ const PACKAGE_NAME_RE = /^[a-zA-Z0-9._]+$/;
19
+ const MAX_PACKAGE_NAME_LENGTH = 255;
20
+ /**
21
+ * Throw `DeviceError({ subtype: "invalid_args" })` if `name` doesn't match
22
+ * the Android package-name grammar. Returns `name` unchanged on success so
23
+ * callers can write `assertValidPackageName(args.pkg)` inline.
24
+ *
25
+ * Empty / non-string / over-length inputs all reject. Defaults inherit
26
+ * `userActionable=true` from the `invalid_args` subtype so the LLM sees a
27
+ * plain-text actionable response instead of an `isError` protocol failure.
28
+ */
29
+ export function assertValidPackageName(name) {
30
+ if (typeof name !== "string" || name.length === 0) {
31
+ throw new DeviceError("package name must be a non-empty string", { subtype: "invalid_args", retriable: false });
32
+ }
33
+ if (name.length > MAX_PACKAGE_NAME_LENGTH) {
34
+ throw new DeviceError(`package name '${name.slice(0, 32)}…' exceeds ${MAX_PACKAGE_NAME_LENGTH} chars`, { subtype: "invalid_args", retriable: false });
35
+ }
36
+ if (!PACKAGE_NAME_RE.test(name)) {
37
+ throw new DeviceError(`package name '${name}' contains invalid characters (allowed: a-z A-Z 0-9 . _)`, { subtype: "invalid_args", retriable: false });
38
+ }
39
+ return name;
40
+ }
41
+ //# sourceMappingURL=package-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-name.js","sourceRoot":"","sources":["../../src/util/package-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAC3C,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAEpC;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,WAAW,CACnB,yCAAyC,EACzC,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,CAC9C,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;QAC1C,MAAM,IAAI,WAAW,CACnB,iBAAiB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,uBAAuB,QAAQ,EAC/E,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,CAC9C,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,WAAW,CACnB,iBAAiB,IAAI,0DAA0D,EAC/E,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,CAC9C,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@beeos-ai/device-mcp-server",
3
- "version": "0.3.0",
4
- "description": "In-pod HTTP MCP tool server for BeeOS device-agent (Android / desktop / mobile sandboxes).",
3
+ "version": "0.4.2",
4
+ "description": "Singleton multi-device MCP tool server for BeeOS device-agent (Android / desktop / mobile sandboxes). Implements the Model Context Protocol over Streamable HTTP and stdio.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -34,13 +34,15 @@
34
34
  "node": ">=20"
35
35
  },
36
36
  "dependencies": {
37
- "fastify": "^5.8.5",
37
+ "@modelcontextprotocol/sdk": "^1.29.0",
38
+ "express": "^4.22.1",
38
39
  "pino": "^10.3.1",
39
40
  "sharp": "^0.34.5",
40
41
  "zod": "^4.3.6",
41
42
  "@beeos-ai/device-common": "0.3.0"
42
43
  },
43
44
  "devDependencies": {
45
+ "@types/express": "^4.17.25",
44
46
  "@types/node": "^22.0.0",
45
47
  "tsx": "^4.19.0",
46
48
  "typescript": "^5.8.0",
@@ -1,21 +0,0 @@
1
- /**
2
- * action-mapping — translate a unified `Action` (`type+target+payload`) into
3
- * the matching MCP tool name + arguments.
4
- *
5
- * Used by `POST /act` so callers can hand the server a high-level Action and
6
- * skip wiring up a tool name themselves. Mirrors the Python reference's
7
- * `_action_to_call` table.
8
- */
9
- import { type Action, type ActionType } from "@beeos-ai/device-common";
10
- export interface ToolCall {
11
- toolName: string;
12
- args: Record<string, unknown>;
13
- }
14
- export interface UnsupportedActionResult {
15
- /** Terminal verbs (`done`, `fail`, `wait`, `call_for_user`) — server replies
16
- * with `{ ok: true, action }` and does NOT touch the backend. */
17
- terminal: true;
18
- type: ActionType;
19
- }
20
- export type ActionMappingResult = ToolCall | UnsupportedActionResult;
21
- export declare function mapActionToTool(action: Action): ActionMappingResult;
@@ -1,153 +0,0 @@
1
- /**
2
- * action-mapping — translate a unified `Action` (`type+target+payload`) into
3
- * the matching MCP tool name + arguments.
4
- *
5
- * Used by `POST /act` so callers can hand the server a high-level Action and
6
- * skip wiring up a tool name themselves. Mirrors the Python reference's
7
- * `_action_to_call` table.
8
- */
9
- import { TERMINAL_ACTIONS, } from "@beeos-ai/device-common";
10
- export function mapActionToTool(action) {
11
- if (TERMINAL_ACTIONS.has(action.type) || action.type === "wait") {
12
- return { terminal: true, type: action.type };
13
- }
14
- const target = action.target;
15
- const payload = action.payload ?? {};
16
- switch (action.type) {
17
- case "click":
18
- case "tap":
19
- case "double_click":
20
- case "right_click":
21
- case "long_press":
22
- case "move": {
23
- const xy = pointFromTarget(target);
24
- return {
25
- toolName: action.type === "move" ? "move" : action.type,
26
- args: {
27
- ...xy,
28
- ...(action.type === "click" && payload.button ? { button: payload.button } : {}),
29
- ...(action.type === "click" && payload.clicks ? { clicks: payload.clicks } : {}),
30
- ...(action.type === "long_press" && payload.durationMs
31
- ? { durationMs: payload.durationMs }
32
- : {}),
33
- },
34
- };
35
- }
36
- case "drag":
37
- case "swipe": {
38
- const seg = segmentFromTarget(target);
39
- return {
40
- toolName: action.type,
41
- args: {
42
- ...seg,
43
- ...(payload.durationMs ? { durationMs: payload.durationMs } : {}),
44
- },
45
- };
46
- }
47
- case "scroll": {
48
- const xy = target ? pointFromTarget(target) : { x: 0, y: 0 };
49
- return {
50
- toolName: "scroll",
51
- args: {
52
- ...xy,
53
- direction: payload.direction ?? "down",
54
- ...(payload.amount ? { amount: payload.amount } : {}),
55
- },
56
- };
57
- }
58
- case "type":
59
- return {
60
- toolName: "type",
61
- args: { text: payload.text ?? "" },
62
- };
63
- case "key":
64
- return {
65
- toolName: "key",
66
- args: { key: payload.key ?? payload.keycode ?? "" },
67
- };
68
- case "hotkey":
69
- return {
70
- toolName: "hotkey",
71
- args: { keys: payload.keys ?? [] },
72
- };
73
- case "back":
74
- return { toolName: "back", args: {} };
75
- case "home":
76
- return { toolName: "home", args: {} };
77
- case "navigate":
78
- return {
79
- toolName: "back",
80
- args: {},
81
- };
82
- case "launch_app": {
83
- const fromTarget = target && (target.kind === "text" || target.kind === "selector")
84
- ? target.value
85
- : undefined;
86
- const pkg = fromTarget ??
87
- payload.pkg ??
88
- payload.appName ??
89
- payload.packageOrName ??
90
- payload.package ??
91
- "";
92
- return {
93
- toolName: "launch_app",
94
- args: {
95
- pkg,
96
- ...(payload.activity ? { activity: payload.activity } : {}),
97
- },
98
- };
99
- }
100
- case "screenshot":
101
- return { toolName: "screenshot", args: {} };
102
- case "ui_dump":
103
- return {
104
- toolName: "ui_dump",
105
- args: {
106
- ...(payload.query ? { query: payload.query } : {}),
107
- ...(payload.format ? { format: payload.format } : {}),
108
- },
109
- };
110
- case "execute_command":
111
- case "run_code":
112
- return {
113
- toolName: "execute_command",
114
- args: {
115
- body: payload.body ?? payload.command ?? "",
116
- ...(payload.timeoutS ? { timeoutS: payload.timeoutS } : {}),
117
- ...(payload.cwd ? { cwd: payload.cwd } : {}),
118
- },
119
- };
120
- case "file_read": {
121
- const path = payload.path ??
122
- (target && (target.kind === "text" || target.kind === "selector")
123
- ? target.value
124
- : "");
125
- return { toolName: "file_read", args: { path } };
126
- }
127
- case "file_write": {
128
- const path = payload.path ??
129
- (target && (target.kind === "text" || target.kind === "selector")
130
- ? target.value
131
- : "");
132
- return {
133
- toolName: "file_write",
134
- args: { path, contentB64: payload.contentB64 ?? "" },
135
- };
136
- }
137
- default:
138
- throw new Error(`unsupported action type: ${String(action.type)}`);
139
- }
140
- }
141
- function pointFromTarget(target) {
142
- if (target && target.kind === "point") {
143
- return { x: target.x, y: target.y };
144
- }
145
- throw new TypeError("action.target must be {kind:'point', x, y} for this action type");
146
- }
147
- function segmentFromTarget(target) {
148
- if (target && target.kind === "box") {
149
- return { x1: target.x1, y1: target.y1, x2: target.x2, y2: target.y2 };
150
- }
151
- throw new TypeError("action.target must be {kind:'box', x1, y1, x2, y2} for this action type");
152
- }
153
- //# sourceMappingURL=action-mapping.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"action-mapping.js","sourceRoot":"","sources":["../../src/server/action-mapping.ts"],"names":[],"mappings":"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"}