@beeos-ai/device-mcp-server 0.2.3
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/LICENSE +201 -0
- package/dist/backends/android-adb-runner.d.ts +32 -0
- package/dist/backends/android-adb-runner.js +15 -0
- package/dist/backends/android-adb-runner.js.map +1 -0
- package/dist/backends/android-adb.d.ts +153 -0
- package/dist/backends/android-adb.js +723 -0
- package/dist/backends/android-adb.js.map +1 -0
- package/dist/backends/base.d.ts +150 -0
- package/dist/backends/base.js +116 -0
- package/dist/backends/base.js.map +1 -0
- package/dist/backends/desktop.d.ts +62 -0
- package/dist/backends/desktop.js +176 -0
- package/dist/backends/desktop.js.map +1 -0
- package/dist/backends/index.d.ts +63 -0
- package/dist/backends/index.js +105 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/linux.d.ts +69 -0
- package/dist/backends/linux.js +230 -0
- package/dist/backends/linux.js.map +1 -0
- package/dist/backends/mac.d.ts +154 -0
- package/dist/backends/mac.js +881 -0
- package/dist/backends/mac.js.map +1 -0
- package/dist/backends/stubs/ios.d.ts +17 -0
- package/dist/backends/stubs/ios.js +32 -0
- package/dist/backends/stubs/ios.js.map +1 -0
- package/dist/backends/stubs/macos.d.ts +13 -0
- package/dist/backends/stubs/macos.js +27 -0
- package/dist/backends/stubs/macos.js.map +1 -0
- package/dist/backends/stubs/windows.d.ts +69 -0
- package/dist/backends/stubs/windows.js +191 -0
- package/dist/backends/stubs/windows.js.map +1 -0
- package/dist/cli.d.ts +37 -0
- package/dist/cli.js +177 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/server/action-mapping.d.ts +21 -0
- package/dist/server/action-mapping.js +153 -0
- package/dist/server/action-mapping.js.map +1 -0
- package/dist/server/app.d.ts +23 -0
- package/dist/server/app.js +157 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/tool-registry.d.ts +50 -0
- package/dist/server/tool-registry.js +504 -0
- package/dist/server/tool-registry.js.map +1 -0
- package/dist/util/adb-files.d.ts +92 -0
- package/dist/util/adb-files.js +221 -0
- package/dist/util/adb-files.js.map +1 -0
- package/dist/util/adb-shell.d.ts +80 -0
- package/dist/util/adb-shell.js +102 -0
- package/dist/util/adb-shell.js.map +1 -0
- package/dist/util/android-apps.d.ts +10 -0
- package/dist/util/android-apps.js +103 -0
- package/dist/util/android-apps.js.map +1 -0
- package/dist/util/image-dim.d.ts +27 -0
- package/dist/util/image-dim.js +37 -0
- package/dist/util/image-dim.js.map +1 -0
- package/dist/util/ui-xml.d.ts +20 -0
- package/dist/util/ui-xml.js +184 -0
- package/dist/util/ui-xml.js.map +1 -0
- package/package.json +56 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @beeos-ai/device-mcp-server — public surface.
|
|
3
|
+
*
|
|
4
|
+
* Most callers use the CLI (`device-mcp-server`) and reach the server over
|
|
5
|
+
* HTTP. The exports here are for embedders that want to host a server in
|
|
6
|
+
* the same Node process (e.g. integration tests, custom orchestration).
|
|
7
|
+
*/
|
|
8
|
+
export { buildApp, type BuildAppOptions } from "./server/app.js";
|
|
9
|
+
export { TOOLS, getTool, listToolDescriptors, type ToolEntry, type ToolHandler, type ToolHandlerContext, } from "./server/tool-registry.js";
|
|
10
|
+
export { mapActionToTool, type ActionMappingResult, type ToolCall, type UnsupportedActionResult, } from "./server/action-mapping.js";
|
|
11
|
+
export { AndroidAdbBackend, DesktopBackend, WindowsBackend, MacOsBackend, IosBackend, createBackend, SUPPORTED_BACKENDS, type BackendName, type SandboxBackend, type BackendFamily, type AndroidAdbBackendOptions, type DesktopBackendOptions, type CreateBackendOptions, } from "./backends/index.js";
|
|
12
|
+
export { BaseSandboxBackend, type ScreenSize, type UiDumpOutput, type ExecuteCommandOutput, type ListDirectoryEntry, } from "./backends/base.js";
|
|
13
|
+
export declare const VERSION = "0.2.0";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @beeos-ai/device-mcp-server — public surface.
|
|
3
|
+
*
|
|
4
|
+
* Most callers use the CLI (`device-mcp-server`) and reach the server over
|
|
5
|
+
* HTTP. The exports here are for embedders that want to host a server in
|
|
6
|
+
* the same Node process (e.g. integration tests, custom orchestration).
|
|
7
|
+
*/
|
|
8
|
+
export { buildApp } from "./server/app.js";
|
|
9
|
+
export { TOOLS, getTool, listToolDescriptors, } from "./server/tool-registry.js";
|
|
10
|
+
export { mapActionToTool, } from "./server/action-mapping.js";
|
|
11
|
+
export { AndroidAdbBackend, DesktopBackend, WindowsBackend, MacOsBackend, IosBackend, createBackend, SUPPORTED_BACKENDS, } from "./backends/index.js";
|
|
12
|
+
export { BaseSandboxBackend, } from "./backends/base.js";
|
|
13
|
+
export const VERSION = "0.2.0";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAwB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EACL,KAAK,EACL,OAAO,EACP,mBAAmB,GAIpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,eAAe,GAIhB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,UAAU,EACV,aAAa,EACb,kBAAkB,GAOnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,kBAAkB,GAKnB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
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;
|
|
@@ -0,0 +1,153 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-mapping.js","sourceRoot":"","sources":["../../src/server/action-mapping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fastify factory — `buildApp({ backend })` returns a configured `FastifyInstance`
|
|
3
|
+
* with all routes wired up. Decoupled from `cli.ts` so unit tests can spin up
|
|
4
|
+
* an in-process server with a mock backend.
|
|
5
|
+
*
|
|
6
|
+
* Routes (mirrors the Python `mcp_tools/server.py` reference):
|
|
7
|
+
* GET /healthz — liveness + backend OS + tool list
|
|
8
|
+
* POST /mcp/tools/list — MCP tool discovery
|
|
9
|
+
* POST /mcp/tools/call — invoke a single MCP tool
|
|
10
|
+
* POST /act — translate `Action` → tool call
|
|
11
|
+
* GET /screen.png — fast-path screenshot (no JSON envelope)
|
|
12
|
+
* GET /events — SSE event stream (placeholder, no consumers yet)
|
|
13
|
+
*/
|
|
14
|
+
import { type FastifyInstance } from "fastify";
|
|
15
|
+
import type { SandboxBackend } from "../backends/base.js";
|
|
16
|
+
export interface BuildAppOptions {
|
|
17
|
+
backend: SandboxBackend;
|
|
18
|
+
/** Override Fastify's logger. Pass `false` to silence in tests. */
|
|
19
|
+
logger?: boolean | object;
|
|
20
|
+
/** Per-request body size cap (bytes). Defaults to 16MB for file_write base64. */
|
|
21
|
+
bodyLimit?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function buildApp(opts: BuildAppOptions): Promise<FastifyInstance>;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fastify factory — `buildApp({ backend })` returns a configured `FastifyInstance`
|
|
3
|
+
* with all routes wired up. Decoupled from `cli.ts` so unit tests can spin up
|
|
4
|
+
* an in-process server with a mock backend.
|
|
5
|
+
*
|
|
6
|
+
* Routes (mirrors the Python `mcp_tools/server.py` reference):
|
|
7
|
+
* GET /healthz — liveness + backend OS + tool list
|
|
8
|
+
* POST /mcp/tools/list — MCP tool discovery
|
|
9
|
+
* POST /mcp/tools/call — invoke a single MCP tool
|
|
10
|
+
* POST /act — translate `Action` → tool call
|
|
11
|
+
* GET /screen.png — fast-path screenshot (no JSON envelope)
|
|
12
|
+
* GET /events — SSE event stream (placeholder, no consumers yet)
|
|
13
|
+
*/
|
|
14
|
+
import Fastify from "fastify";
|
|
15
|
+
import { AcpError, DeviceError, VlmError, } from "@beeos-ai/device-common";
|
|
16
|
+
import { mapActionToTool } from "./action-mapping.js";
|
|
17
|
+
import { getToolFor, listToolDescriptorsFor } from "./tool-registry.js";
|
|
18
|
+
export async function buildApp(opts) {
|
|
19
|
+
const app = Fastify({
|
|
20
|
+
logger: opts.logger ?? true,
|
|
21
|
+
bodyLimit: opts.bodyLimit ?? 16 * 1024 * 1024,
|
|
22
|
+
});
|
|
23
|
+
app.setErrorHandler((err, _req, reply) => {
|
|
24
|
+
if (err instanceof DeviceError) {
|
|
25
|
+
const status = err.subtype === "unsupported" ? 501 : err.subtype === "invalid_args" ? 400 : 500;
|
|
26
|
+
reply
|
|
27
|
+
.status(status)
|
|
28
|
+
.send({ error: err.message, subtype: err.subtype, retriable: err.retriable });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (err instanceof AcpError) {
|
|
32
|
+
reply.status(400).send({ error: err.message, code: err.code });
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (err instanceof VlmError) {
|
|
36
|
+
reply.status(400).send({ error: err.message, retriable: err.retriable });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
reply.status(500).send({ error: err?.message ?? "internal error" });
|
|
40
|
+
});
|
|
41
|
+
/* ---------- /healthz ---------- */
|
|
42
|
+
app.get("/healthz", async () => {
|
|
43
|
+
return {
|
|
44
|
+
ok: true,
|
|
45
|
+
// Wire field name kept as `backend` even though the source is
|
|
46
|
+
// now `os` rather than `family`. Values are unchanged
|
|
47
|
+
// (`"android"` / `"desktop-macos"` / etc) — see the BackendOs
|
|
48
|
+
// taxonomy in @beeos-ai/device-common/backend.ts.
|
|
49
|
+
backend: opts.backend.os,
|
|
50
|
+
version: process.env.npm_package_version ?? "0.2.0",
|
|
51
|
+
// Tool-set-filtered list — agents that pick a tool out of this
|
|
52
|
+
// list are guaranteed it'll dispatch on the active backend.
|
|
53
|
+
tools: listToolDescriptorsFor(opts.backend).map((t) => t.name),
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
/* ---------- /mcp/tools/list ---------- */
|
|
57
|
+
const toolListHandler = async () => ({
|
|
58
|
+
tools: listToolDescriptorsFor(opts.backend),
|
|
59
|
+
});
|
|
60
|
+
app.get("/mcp/tools/list", toolListHandler);
|
|
61
|
+
app.post("/mcp/tools/list", toolListHandler);
|
|
62
|
+
/* ---------- /mcp/tools/call ---------- */
|
|
63
|
+
app.post("/mcp/tools/call", async (req, reply) => {
|
|
64
|
+
const { name, arguments: args = {} } = req.body ?? {};
|
|
65
|
+
if (!name || typeof name !== "string") {
|
|
66
|
+
reply.status(400).send({ error: "missing tool name" });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const tool = getToolFor(name, opts.backend);
|
|
70
|
+
if (!tool) {
|
|
71
|
+
// Either the tool is unknown OR the backend lacks the required
|
|
72
|
+
// capability — collapse both to 404 so MCP clients reading
|
|
73
|
+
// `/mcp/tools/list` cannot bypass the filter via direct call.
|
|
74
|
+
reply.status(404).send({ error: `unknown tool '${name}'` });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const startedAt = Date.now();
|
|
78
|
+
try {
|
|
79
|
+
const result = await tool.handler(args, { backend: opts.backend });
|
|
80
|
+
const response = {
|
|
81
|
+
ok: true,
|
|
82
|
+
tool: name,
|
|
83
|
+
durationMs: Date.now() - startedAt,
|
|
84
|
+
result,
|
|
85
|
+
};
|
|
86
|
+
reply.send(response);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
if (e instanceof DeviceError)
|
|
90
|
+
throw e;
|
|
91
|
+
if (e instanceof Error && e.name === "TypeError") {
|
|
92
|
+
reply.status(400).send({ error: e.message });
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
throw e;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
/* ---------- /act ---------- */
|
|
99
|
+
app.post("/act", async (req, reply) => {
|
|
100
|
+
const action = req.body?.action;
|
|
101
|
+
if (!action || typeof action.type !== "string") {
|
|
102
|
+
reply.status(400).send({ error: "missing or malformed action" });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const startedAt = Date.now();
|
|
106
|
+
const mapped = mapActionToTool(action);
|
|
107
|
+
if ("terminal" in mapped) {
|
|
108
|
+
const response = {
|
|
109
|
+
ok: true,
|
|
110
|
+
action: mapped.type,
|
|
111
|
+
terminal: true,
|
|
112
|
+
durationMs: Date.now() - startedAt,
|
|
113
|
+
};
|
|
114
|
+
reply.send(response);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const tool = getToolFor(mapped.toolName, opts.backend);
|
|
118
|
+
if (!tool) {
|
|
119
|
+
reply.status(404).send({ error: `tool '${mapped.toolName}' not registered` });
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const result = await tool.handler(mapped.args, { backend: opts.backend });
|
|
123
|
+
const response = {
|
|
124
|
+
ok: true,
|
|
125
|
+
action: action.type,
|
|
126
|
+
tool: mapped.toolName,
|
|
127
|
+
durationMs: Date.now() - startedAt,
|
|
128
|
+
result,
|
|
129
|
+
};
|
|
130
|
+
reply.send(response);
|
|
131
|
+
});
|
|
132
|
+
/* ---------- /screen.png ---------- */
|
|
133
|
+
app.get("/screen.png", async (_req, reply) => {
|
|
134
|
+
// 0.2.3: backend reports the encoded format directly so we never
|
|
135
|
+
// need to magic-byte-sniff the buffer here.
|
|
136
|
+
const shot = await opts.backend.screenshot();
|
|
137
|
+
reply
|
|
138
|
+
.header("content-type", shot.format === "png" ? "image/png" : "image/jpeg")
|
|
139
|
+
.send(shot.data);
|
|
140
|
+
});
|
|
141
|
+
/* ---------- /events (SSE placeholder) ---------- */
|
|
142
|
+
app.get("/events", async (_req, reply) => {
|
|
143
|
+
reply.raw.writeHead(200, {
|
|
144
|
+
"Content-Type": "text/event-stream",
|
|
145
|
+
"Cache-Control": "no-cache",
|
|
146
|
+
Connection: "keep-alive",
|
|
147
|
+
});
|
|
148
|
+
reply.raw.write(": connected\n\n");
|
|
149
|
+
const interval = setInterval(() => {
|
|
150
|
+
reply.raw.write(`: heartbeat ${Date.now()}\n\n`);
|
|
151
|
+
}, 15_000);
|
|
152
|
+
reply.raw.on("close", () => clearInterval(interval));
|
|
153
|
+
return reply;
|
|
154
|
+
});
|
|
155
|
+
return app;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool registry — verbs exposed by the device sandbox.
|
|
3
|
+
*
|
|
4
|
+
* Each tool entry carries:
|
|
5
|
+
* - a name (the MCP tool identifier, e.g. `click`)
|
|
6
|
+
* - a JSON schema describing the expected `arguments` payload
|
|
7
|
+
* - a `handler` that maps `arguments` → `SandboxBackend` method call.
|
|
8
|
+
*
|
|
9
|
+
* Filtering is driven entirely by `backend.tools` (a flat
|
|
10
|
+
* `ReadonlySet<string>` declared on each backend). The registry is
|
|
11
|
+
* purely a name → schema/handler lookup table; it does not encode
|
|
12
|
+
* support gates of its own. `listToolDescriptorsFor(backend)` filters
|
|
13
|
+
* via `backend.tools.has(name)`; `getToolFor(name, backend)` mirrors
|
|
14
|
+
* the same gate so `/mcp/tools/call` returns 404 (instead of 200 +
|
|
15
|
+
* runtime `unsupported`) for any tool the active backend doesn't
|
|
16
|
+
* advertise.
|
|
17
|
+
*
|
|
18
|
+
* Inspired by the Python `mcp_tools/registry.py` reference; verbs are kept
|
|
19
|
+
* verbatim for cross-runtime compatibility.
|
|
20
|
+
*/
|
|
21
|
+
import type { ToolDescriptor } from "@beeos-ai/device-common";
|
|
22
|
+
import type { SandboxBackend } from "../backends/base.js";
|
|
23
|
+
export interface ToolHandlerContext {
|
|
24
|
+
backend: SandboxBackend;
|
|
25
|
+
}
|
|
26
|
+
export type ToolHandler = (args: Record<string, unknown>, ctx: ToolHandlerContext) => Promise<unknown>;
|
|
27
|
+
export interface ToolEntry {
|
|
28
|
+
descriptor: ToolDescriptor;
|
|
29
|
+
handler: ToolHandler;
|
|
30
|
+
}
|
|
31
|
+
export declare const TOOLS: Record<string, ToolEntry>;
|
|
32
|
+
/**
|
|
33
|
+
* Return ALL registered tool descriptors regardless of backend support.
|
|
34
|
+
*
|
|
35
|
+
* Useful for documentation / tests that want to enumerate the catalog.
|
|
36
|
+
* Wire callers SHOULD use `listToolDescriptorsFor(backend)` so the list
|
|
37
|
+
* only contains tools the active backend can actually execute.
|
|
38
|
+
*/
|
|
39
|
+
export declare function listToolDescriptors(): ToolDescriptor[];
|
|
40
|
+
/** Return tool descriptors filtered by the backend's advertised tool set. */
|
|
41
|
+
export declare function listToolDescriptorsFor(backend: SandboxBackend): ToolDescriptor[];
|
|
42
|
+
/** Look up a tool by name, ignoring backend tool-set gates. */
|
|
43
|
+
export declare function getTool(name: string): ToolEntry | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Look up a tool by name, **gated** on the backend's advertised tool
|
|
46
|
+
* set. Returns `undefined` for tools the active backend cannot
|
|
47
|
+
* satisfy — the `/mcp/tools/call` route uses this and returns 404,
|
|
48
|
+
* mirroring the filtering applied at `/mcp/tools/list`.
|
|
49
|
+
*/
|
|
50
|
+
export declare function getToolFor(name: string, backend: SandboxBackend): ToolEntry | undefined;
|