@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.
- package/dist/backends/android-adb.d.ts +147 -6
- package/dist/backends/android-adb.js +776 -40
- package/dist/backends/android-adb.js.map +1 -1
- package/dist/backends/base.d.ts +243 -7
- package/dist/backends/base.js +81 -2
- package/dist/backends/base.js.map +1 -1
- package/dist/backends/desktop.d.ts +3 -2
- package/dist/backends/desktop.js +9 -3
- package/dist/backends/desktop.js.map +1 -1
- package/dist/backends/linux.js +3 -0
- package/dist/backends/linux.js.map +1 -1
- package/dist/backends/mac.d.ts +11 -2
- package/dist/backends/mac.js +39 -1
- package/dist/backends/mac.js.map +1 -1
- package/dist/backends/stubs/windows.js +3 -0
- package/dist/backends/stubs/windows.js.map +1 -1
- package/dist/cli.d.ts +40 -26
- package/dist/cli.js +118 -84
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/server/app.d.ts +60 -17
- package/dist/server/app.js +182 -138
- package/dist/server/app.js.map +1 -1
- package/dist/server/mcp-server.d.ts +25 -0
- package/dist/server/mcp-server.js +33 -0
- package/dist/server/mcp-server.js.map +1 -0
- package/dist/server/registry.d.ts +111 -0
- package/dist/server/registry.js +191 -0
- package/dist/server/registry.js.map +1 -0
- package/dist/server/stdio.d.ts +29 -0
- package/dist/server/stdio.js +35 -0
- package/dist/server/stdio.js.map +1 -0
- package/dist/server/tool-registry.d.ts +60 -35
- package/dist/server/tool-registry.js +911 -434
- package/dist/server/tool-registry.js.map +1 -1
- package/dist/util/adb-files.d.ts +25 -1
- package/dist/util/adb-files.js +95 -0
- package/dist/util/adb-files.js.map +1 -1
- package/dist/util/locale.d.ts +16 -0
- package/dist/util/locale.js +31 -0
- package/dist/util/locale.js.map +1 -0
- package/dist/util/logger.d.ts +27 -0
- package/dist/util/logger.js +27 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/output-path.d.ts +60 -0
- package/dist/util/output-path.js +123 -0
- package/dist/util/output-path.js.map +1 -0
- package/dist/util/package-name.d.ts +26 -0
- package/dist/util/package-name.js +41 -0
- package/dist/util/package-name.js.map +1 -0
- package/package.json +5 -3
- package/dist/server/action-mapping.d.ts +0 -21
- package/dist/server/action-mapping.js +0 -153
- package/dist/server/action-mapping.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,52 +1,68 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* device-mcp-server CLI —
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* `device-mcp-server` CLI — singleton multi-device MCP server.
|
|
4
|
+
*
|
|
5
|
+
* 0.4.0 reshape:
|
|
6
|
+
* - Switched from a per-device process model to a singleton: one
|
|
7
|
+
* `device-mcp-server` discovers every adb device in `adb devices`
|
|
8
|
+
* and exposes them as separate `device` ids on every tool call (just
|
|
9
|
+
* like Mobile-Next/mobile-mcp). The `--adb-serial` flag from 0.3.x
|
|
10
|
+
* is REMOVED — multi-device discovery is the only supported mode.
|
|
11
|
+
* - Switched the wire from a bespoke REST envelope to the official
|
|
12
|
+
* Model Context Protocol over `@modelcontextprotocol/sdk`.
|
|
13
|
+
* - Two transports:
|
|
14
|
+
* HTTP (default) Express + Streamable HTTP at `POST /mcp`
|
|
15
|
+
* stdio (--stdio) Single-session JSON-RPC over stdin/stdout
|
|
7
16
|
*
|
|
8
17
|
* Examples:
|
|
9
|
-
*
|
|
10
|
-
* device-mcp-server --backend desktop --port
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* device-mcp-server --backend
|
|
18
|
+
* # HTTP loopback for `device-agent` siblings
|
|
19
|
+
* device-mcp-server --backend desktop --port 7900
|
|
20
|
+
*
|
|
21
|
+
* # IDE / Cursor stdio entry — JSON-RPC on stdin/stdout, logs on stderr
|
|
22
|
+
* device-mcp-server --backend desktop --stdio
|
|
23
|
+
*
|
|
24
|
+
* # Android farm — server discovers every adb device and exposes them
|
|
25
|
+
* # as separate `device` ids. Pass `device: <serial>` per tool call.
|
|
26
|
+
* device-mcp-server --backend adb --port 7900
|
|
14
27
|
*
|
|
15
28
|
* Env overrides:
|
|
16
29
|
* DEVICEAGENT_BACKEND=adb|macos|linux|windows|desktop|...
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
30
|
+
* ADB_DEFAULT_TIMEOUT_MS per-call adb command timeout (ms)
|
|
31
|
+
* ADB_SHELL_TIMEOUT_MS adb shell timeout (ms)
|
|
32
|
+
* ADB_SCREENSHOT_TIMEOUT_MS adb exec-out screencap timeout (ms)
|
|
33
|
+
* ADB_INSTALL_TIMEOUT_MS adb install timeout (ms)
|
|
34
|
+
* MAC_CLICLICK_PATH override autodetected cliclick path
|
|
35
|
+
* MCP_HOST HTTP bind address (default 127.0.0.1)
|
|
36
|
+
* MCP_PORT HTTP listen port (default 7900)
|
|
37
|
+
* DEVICE_MCP_POLL_MS adb-discovery poll interval (default 10000)
|
|
38
|
+
* GUI_AGENT_SS_MAX_EDGE screenshot resize cap (default 1280)
|
|
39
|
+
* GUI_AGENT_SS_JPEG_QUALITY screenshot JPEG quality (default 80)
|
|
25
40
|
*
|
|
26
41
|
* macOS notes:
|
|
27
|
-
* - The
|
|
28
|
-
* local Mac via cliclick + osascript + screencapture. The host
|
|
29
|
-
* MUST hold Accessibility permission (System Settings →
|
|
30
|
-
* Security → Accessibility) for synthetic input to take
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* itself has no scroll command; scroll is always JXA-driven).
|
|
42
|
+
* - The `macos` backend (and `desktop` on a darwin host) drives the
|
|
43
|
+
* real local Mac via cliclick + osascript + screencapture. The host
|
|
44
|
+
* process MUST hold Accessibility permission (System Settings →
|
|
45
|
+
* Privacy & Security → Accessibility) for synthetic input to take
|
|
46
|
+
* effect.
|
|
47
|
+
* - cliclick is auto-detected on PATH; install via `brew install
|
|
48
|
+
* cliclick` for the smoothest pointer ergonomics. Without it the
|
|
49
|
+
* backend falls back to JXA + Quartz CGEvent.
|
|
36
50
|
*/
|
|
37
51
|
import { parseArgs } from "node:util";
|
|
38
52
|
import { DeviceError } from "@beeos-ai/device-common";
|
|
39
53
|
import { createBackend, SUPPORTED_BACKENDS } from "./backends/index.js";
|
|
40
54
|
import { buildApp } from "./server/app.js";
|
|
55
|
+
import { runStdio } from "./server/stdio.js";
|
|
56
|
+
import { BackendRegistry } from "./server/registry.js";
|
|
57
|
+
import { stderrLogger } from "./util/logger.js";
|
|
41
58
|
function parseCliArgs(argv) {
|
|
42
59
|
const { values } = parseArgs({
|
|
43
60
|
args: argv,
|
|
44
61
|
options: {
|
|
45
62
|
backend: { type: "string" },
|
|
46
|
-
"adb-serial": { type: "string" },
|
|
47
63
|
host: { type: "string" },
|
|
48
64
|
port: { type: "string" },
|
|
49
|
-
|
|
65
|
+
stdio: { type: "boolean", default: false },
|
|
50
66
|
width: { type: "string" },
|
|
51
67
|
height: { type: "string" },
|
|
52
68
|
help: { type: "boolean", short: "h", default: false },
|
|
@@ -58,7 +74,7 @@ function parseCliArgs(argv) {
|
|
|
58
74
|
printHelp();
|
|
59
75
|
process.exit(0);
|
|
60
76
|
}
|
|
61
|
-
const backendName = (values.backend ?? process.env.DEVICEAGENT_BACKEND ?? "
|
|
77
|
+
const backendName = (values.backend ?? process.env.DEVICEAGENT_BACKEND ?? "adb");
|
|
62
78
|
if (!SUPPORTED_BACKENDS.includes(backendName)) {
|
|
63
79
|
throw new DeviceError(`unknown backend '${backendName}'. Supported: ${SUPPORTED_BACKENDS.join(", ")}`, { subtype: "invalid_args" });
|
|
64
80
|
}
|
|
@@ -70,39 +86,34 @@ function parseCliArgs(argv) {
|
|
|
70
86
|
backend: backendName,
|
|
71
87
|
host: values.host ?? process.env.MCP_HOST ?? "127.0.0.1",
|
|
72
88
|
port,
|
|
73
|
-
|
|
74
|
-
skipConnectValidation: !!values["skip-connect"],
|
|
89
|
+
stdio: !!values.stdio,
|
|
75
90
|
width: values.width ? Number(values.width) : undefined,
|
|
76
91
|
height: values.height ? Number(values.height) : undefined,
|
|
77
92
|
};
|
|
78
93
|
}
|
|
79
94
|
function printHelp() {
|
|
80
|
-
process.stdout.write(`device-mcp-server —
|
|
95
|
+
process.stdout.write(`device-mcp-server — singleton multi-device MCP tool server.
|
|
81
96
|
|
|
82
97
|
Usage:
|
|
83
98
|
device-mcp-server [options]
|
|
84
99
|
|
|
85
100
|
Options:
|
|
86
|
-
--backend <name>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
--host <addr> Bind address (default: 127.0.0.1)
|
|
97
|
-
--port <n> Listen port (default: 7900)
|
|
98
|
-
--skip-connect Skip connect-time backend validation (tests / cold farms)
|
|
99
|
-
--width / --height Override mock-desktop canvas size (ignored on macos)
|
|
100
|
-
-h, --help Show this help
|
|
101
|
+
--backend <name> Canonical: adb | macos | linux | windows | desktop
|
|
102
|
+
Aliases: android (= adb), mac (= macos), win (= windows),
|
|
103
|
+
desktop-{linux,macos,windows}, mock-desktop, ios
|
|
104
|
+
Default: "adb" — the singleton multi-device path.
|
|
105
|
+
--host <addr> HTTP bind address (default: 127.0.0.1; ignored under --stdio)
|
|
106
|
+
--port <n> HTTP listen port (default: 7900; ignored under --stdio)
|
|
107
|
+
--stdio Use stdio transport (single session, JSON-RPC on stdin/stdout,
|
|
108
|
+
logs on stderr). Mutually exclusive with HTTP.
|
|
109
|
+
--width / --height Override mock-desktop canvas size (ignored on macos)
|
|
110
|
+
-h, --help Show this help
|
|
101
111
|
|
|
102
112
|
Env overrides:
|
|
103
|
-
DEVICEAGENT_BACKEND,
|
|
113
|
+
DEVICEAGENT_BACKEND, MCP_HOST, MCP_PORT, MAC_CLICLICK_PATH,
|
|
104
114
|
ADB_DEFAULT_TIMEOUT_MS, ADB_SHELL_TIMEOUT_MS, ADB_SCREENSHOT_TIMEOUT_MS,
|
|
105
|
-
ADB_INSTALL_TIMEOUT_MS
|
|
115
|
+
ADB_INSTALL_TIMEOUT_MS, DEVICE_MCP_POLL_MS,
|
|
116
|
+
GUI_AGENT_SS_MAX_EDGE, GUI_AGENT_SS_JPEG_QUALITY
|
|
106
117
|
`);
|
|
107
118
|
}
|
|
108
119
|
function parsePositiveIntEnv(name) {
|
|
@@ -116,49 +127,73 @@ function parsePositiveIntEnv(name) {
|
|
|
116
127
|
}
|
|
117
128
|
async function main() {
|
|
118
129
|
const cli = parseCliArgs(process.argv.slice(2));
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
130
|
+
// Build the static (non-adb) backend up front. The adb path is handled
|
|
131
|
+
// by the registry's discovery poll — there's no per-process adb pinning
|
|
132
|
+
// any more.
|
|
133
|
+
const isAdb = cli.backend === "adb" || cli.backend === "android";
|
|
134
|
+
const initialBackends = isAdb
|
|
135
|
+
? []
|
|
136
|
+
: [
|
|
137
|
+
createBackend(cli.backend, {
|
|
138
|
+
desktop: { width: cli.width, height: cli.height },
|
|
139
|
+
macos: {
|
|
140
|
+
cliclickPath: process.env.MAC_CLICLICK_PATH || undefined,
|
|
141
|
+
},
|
|
142
|
+
linux: {
|
|
143
|
+
shellTimeoutMs: parsePositiveIntEnv("LINUX_SHELL_TIMEOUT_MS"),
|
|
144
|
+
},
|
|
145
|
+
windows: {
|
|
146
|
+
shellTimeoutMs: parsePositiveIntEnv("WINDOWS_SHELL_TIMEOUT_MS"),
|
|
147
|
+
powershellBin: process.env.WINDOWS_POWERSHELL_BIN || undefined,
|
|
148
|
+
},
|
|
149
|
+
}),
|
|
150
|
+
];
|
|
151
|
+
const registry = new BackendRegistry({
|
|
152
|
+
initialBackends,
|
|
153
|
+
enableAdbDiscovery: isAdb,
|
|
154
|
+
pollIntervalMs: parsePositiveIntEnv("DEVICE_MCP_POLL_MS") ?? undefined,
|
|
155
|
+
androidDefaults: {
|
|
123
156
|
defaultTimeoutMs: parsePositiveIntEnv("ADB_DEFAULT_TIMEOUT_MS"),
|
|
124
157
|
shellTimeoutMs: parsePositiveIntEnv("ADB_SHELL_TIMEOUT_MS"),
|
|
125
158
|
screenshotTimeoutMs: parsePositiveIntEnv("ADB_SCREENSHOT_TIMEOUT_MS"),
|
|
126
159
|
installTimeoutMs: parsePositiveIntEnv("ADB_INSTALL_TIMEOUT_MS"),
|
|
127
160
|
},
|
|
128
|
-
desktop: { width: cli.width, height: cli.height },
|
|
129
|
-
macos: {
|
|
130
|
-
cliclickPath: process.env.MAC_CLICLICK_PATH || undefined,
|
|
131
|
-
},
|
|
132
|
-
linux: {
|
|
133
|
-
shellTimeoutMs: parsePositiveIntEnv("LINUX_SHELL_TIMEOUT_MS"),
|
|
134
|
-
},
|
|
135
|
-
windows: {
|
|
136
|
-
shellTimeoutMs: parsePositiveIntEnv("WINDOWS_SHELL_TIMEOUT_MS"),
|
|
137
|
-
powershellBin: process.env.WINDOWS_POWERSHELL_BIN || undefined,
|
|
138
|
-
},
|
|
139
161
|
});
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
-
cli.backend === "
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
await registry.start();
|
|
163
|
+
// Surface a one-shot warning for macOS Accessibility permission since
|
|
164
|
+
// that's the most common "tools silently no-op" failure mode.
|
|
165
|
+
if (!cli.stdio &&
|
|
166
|
+
((cli.backend === "desktop" && process.platform === "darwin") ||
|
|
167
|
+
cli.backend === "macos" ||
|
|
168
|
+
cli.backend === "mac" ||
|
|
169
|
+
cli.backend === "desktop-macos")) {
|
|
170
|
+
process.stderr.write("[device-mcp-server] macOS backend selected — ensure the host process " +
|
|
149
171
|
"holds Accessibility permission (System Settings → Privacy & Security " +
|
|
150
|
-
"→ Accessibility) for synthetic input to take effect
|
|
172
|
+
"→ Accessibility) for synthetic input to take effect.\n");
|
|
151
173
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
174
|
+
if (cli.stdio) {
|
|
175
|
+
await runStdio({ registry, version: process.env.npm_package_version });
|
|
176
|
+
// runStdio resolves once stdin is wired up; the SDK transport keeps
|
|
177
|
+
// the process alive while stdin is open and exits the loop on EOF.
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const app = buildApp({ registry, version: process.env.npm_package_version });
|
|
181
|
+
const httpServer = app.listen(cli.port, cli.host, () => {
|
|
182
|
+
const addr = httpServer.address();
|
|
183
|
+
const display = typeof addr === "string"
|
|
184
|
+
? addr
|
|
185
|
+
: addr
|
|
186
|
+
? `http://${cli.host}:${addr.port}/mcp`
|
|
187
|
+
: `http://${cli.host}:${cli.port}/mcp`;
|
|
188
|
+
stderrLogger.info?.({ backend: cli.backend, address: display }, "device-mcp-server listening");
|
|
189
|
+
});
|
|
155
190
|
const shutdown = async (signal) => {
|
|
156
|
-
|
|
191
|
+
stderrLogger.info?.({ signal }, "shutting down");
|
|
157
192
|
try {
|
|
158
|
-
await
|
|
159
|
-
await backend.disconnect();
|
|
193
|
+
await new Promise((res) => httpServer.close(() => res()));
|
|
160
194
|
}
|
|
161
195
|
finally {
|
|
196
|
+
await registry.stop().catch(() => undefined);
|
|
162
197
|
process.exit(0);
|
|
163
198
|
}
|
|
164
199
|
};
|
|
@@ -166,11 +201,10 @@ async function main() {
|
|
|
166
201
|
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
167
202
|
}
|
|
168
203
|
main().catch((err) => {
|
|
169
|
-
|
|
170
|
-
|
|
204
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
205
|
+
process.stderr.write(`[device-mcp-server] fatal: ${message}\n`);
|
|
171
206
|
if (err instanceof DeviceError) {
|
|
172
|
-
|
|
173
|
-
console.error(` subtype=${err.subtype} retriable=${err.retriable}`);
|
|
207
|
+
process.stderr.write(` subtype=${err.subtype} retriable=${err.retriable}\n`);
|
|
174
208
|
}
|
|
175
209
|
process.exit(1);
|
|
176
210
|
});
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @beeos-ai/device-mcp-server — public surface.
|
|
2
|
+
* @beeos-ai/device-mcp-server — public surface (0.4.0).
|
|
3
3
|
*
|
|
4
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
|
|
6
|
-
* the same Node process (e.g. integration tests, custom
|
|
5
|
+
* HTTP / stdio. The exports here are for embedders that want to host the
|
|
6
|
+
* server in the same Node process (e.g. integration tests, custom
|
|
7
|
+
* orchestration, IDE plugins).
|
|
7
8
|
*/
|
|
8
9
|
export { buildApp, type BuildAppOptions } from "./server/app.js";
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
10
|
+
export { runStdio, type RunStdioOptions } from "./server/stdio.js";
|
|
11
|
+
export { buildMcpServer, type BuildMcpServerOptions } from "./server/mcp-server.js";
|
|
12
|
+
export { BackendRegistry, type AvailableDevice as RegistryAvailableDevice, type BackendRegistryOptions, } from "./server/registry.js";
|
|
13
|
+
export { TOOL_SPECS, allToolNames, getToolSpec, registerAllTools, type ToolHandler, type ToolHandlerContext, type ToolSpec, } from "./server/tool-registry.js";
|
|
11
14
|
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
15
|
export { BaseSandboxBackend, type ScreenSize, type UiDumpOutput, type ExecuteCommandOutput, type ListDirectoryEntry, } from "./backends/base.js";
|
|
13
|
-
export declare const VERSION = "0.
|
|
16
|
+
export declare const VERSION = "0.4.0";
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @beeos-ai/device-mcp-server — public surface.
|
|
2
|
+
* @beeos-ai/device-mcp-server — public surface (0.4.0).
|
|
3
3
|
*
|
|
4
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
|
|
6
|
-
* the same Node process (e.g. integration tests, custom
|
|
5
|
+
* HTTP / stdio. The exports here are for embedders that want to host the
|
|
6
|
+
* server in the same Node process (e.g. integration tests, custom
|
|
7
|
+
* orchestration, IDE plugins).
|
|
7
8
|
*/
|
|
8
9
|
export { buildApp } from "./server/app.js";
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
10
|
+
export { runStdio } from "./server/stdio.js";
|
|
11
|
+
export { buildMcpServer } from "./server/mcp-server.js";
|
|
12
|
+
export { BackendRegistry, } from "./server/registry.js";
|
|
13
|
+
export { TOOL_SPECS, allToolNames, getToolSpec, registerAllTools, } from "./server/tool-registry.js";
|
|
11
14
|
export { AndroidAdbBackend, DesktopBackend, WindowsBackend, MacOsBackend, IosBackend, createBackend, SUPPORTED_BACKENDS, } from "./backends/index.js";
|
|
12
15
|
export { BaseSandboxBackend, } from "./backends/base.js";
|
|
13
|
-
export const VERSION = "0.
|
|
16
|
+
export const VERSION = "0.4.0";
|
|
14
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAwB,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAwB,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,cAAc,EAA8B,MAAM,wBAAwB,CAAC;AACpF,OAAO,EACL,eAAe,GAGhB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,UAAU,EACV,YAAY,EACZ,WAAW,EACX,gBAAgB,GAIjB,MAAM,2BAA2B,CAAC;AAEnC,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"}
|
package/dist/server/app.d.ts
CHANGED
|
@@ -1,23 +1,66 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
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.
|
|
2
|
+
* Express HTTP host for `device-mcp-server`'s Streamable HTTP transport.
|
|
5
3
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
4
|
+
* 0.4.0 reshape: the previous Fastify routes (`/healthz`, `/mcp/tools/list`,
|
|
5
|
+
* `/mcp/tools/call`, `/act`, `/screen.png`, `/events`) are GONE. The only
|
|
6
|
+
* surface this app exposes is `POST /mcp` — the Streamable HTTP endpoint
|
|
7
|
+
* defined by the official MCP wire spec, hosted by
|
|
8
|
+
* `@modelcontextprotocol/sdk`'s `StreamableHTTPServerTransport`.
|
|
9
|
+
*
|
|
10
|
+
* Stateless mode is intentional:
|
|
11
|
+
* - `sessionIdGenerator: undefined` → no session header, no in-memory
|
|
12
|
+
* subscriber map, every POST is fully self-contained.
|
|
13
|
+
* - GET / DELETE on `/mcp` return 405 — those verbs only make sense in
|
|
14
|
+
* stateful (subscribe-for-notifications) mode which we don't use.
|
|
15
|
+
* - The transport is recreated per request so concurrent calls don't
|
|
16
|
+
* trip over a shared `_initialized` flag (this matches the SDK
|
|
17
|
+
* stateless example in the README).
|
|
18
|
+
*
|
|
19
|
+
* Auth (0.4.1): the loopback server still binds to `127.0.0.1` by
|
|
20
|
+
* default and is safe in that posture. When the operator exposes it on
|
|
21
|
+
* a routable interface (`--host 0.0.0.0`, container forwarding, …) two
|
|
22
|
+
* defence-in-depth gates kick in:
|
|
23
|
+
*
|
|
24
|
+
* - `BEEOS_DEVICE_AUTH=<token>` → `Authorization: Bearer <token>` is
|
|
25
|
+
* required on every `POST /mcp`. Constant-time compared so the
|
|
26
|
+
* check doesn't leak length differences.
|
|
27
|
+
* - `BEEOS_DEVICE_ALLOWED_ORIGINS=https://a,https://b` → if the
|
|
28
|
+
* incoming request carries an `Origin` header it must match one of
|
|
29
|
+
* the listed origins. Browser callers without an origin (curl /
|
|
30
|
+
* server-to-server) are still allowed unless `BEEOS_DEVICE_REQUIRE_ORIGIN=1`.
|
|
31
|
+
*
|
|
32
|
+
* Both are optional — leaving them unset preserves the legacy "loopback
|
|
33
|
+
* is trusted" stance.
|
|
13
34
|
*/
|
|
14
|
-
import { type
|
|
15
|
-
import type {
|
|
35
|
+
import { type Express } from "express";
|
|
36
|
+
import type { BackendRegistry } from "./registry.js";
|
|
37
|
+
import { type Logger } from "../util/logger.js";
|
|
16
38
|
export interface BuildAppOptions {
|
|
17
|
-
|
|
18
|
-
/** Override
|
|
19
|
-
|
|
20
|
-
/**
|
|
39
|
+
registry: BackendRegistry;
|
|
40
|
+
/** Override the advertised server `name`. */
|
|
41
|
+
name?: string;
|
|
42
|
+
/** Override the advertised server `version`. */
|
|
43
|
+
version?: string;
|
|
44
|
+
/** Per-request body size cap (bytes). Defaults to 16MB for `file_write` base64. */
|
|
21
45
|
bodyLimit?: number;
|
|
46
|
+
/** Pino-shaped logger. Defaults to a stderr-only logger so stdio mode is safe. */
|
|
47
|
+
logger?: Logger;
|
|
48
|
+
/**
|
|
49
|
+
* Bearer token required on every `POST /mcp` (`Authorization: Bearer
|
|
50
|
+
* <token>`). When undefined, falls back to `BEEOS_DEVICE_AUTH` env.
|
|
51
|
+
* Empty string explicitly disables auth (overrides env).
|
|
52
|
+
*/
|
|
53
|
+
authToken?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Comma-separated allow-list for the `Origin` header. When undefined,
|
|
56
|
+
* falls back to `BEEOS_DEVICE_ALLOWED_ORIGINS`. Empty string disables
|
|
57
|
+
* origin enforcement.
|
|
58
|
+
*/
|
|
59
|
+
allowedOrigins?: string;
|
|
60
|
+
/**
|
|
61
|
+
* If true, requests without an `Origin` header are also rejected.
|
|
62
|
+
* Defaults to `BEEOS_DEVICE_REQUIRE_ORIGIN === "1"`.
|
|
63
|
+
*/
|
|
64
|
+
requireOrigin?: boolean;
|
|
22
65
|
}
|
|
23
|
-
export declare function buildApp(opts: BuildAppOptions):
|
|
66
|
+
export declare function buildApp(opts: BuildAppOptions): Express;
|