@iobroker/mcp-server 1.5.0 → 1.6.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/README.md +14 -4
- package/build/devices.d.ts +1 -1
- package/build/devices.js +1 -1
- package/build/index.d.ts +31 -4
- package/build/index.js +176 -97
- package/build/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,10 +45,13 @@ The adapter can be configured through the ioBroker admin interface using JSONCon
|
|
|
45
45
|
endpoint is reachable without credentials — only use that on a trusted network or behind a reverse proxy
|
|
46
46
|
that provides its own authentication. As a **web extension** the host `web` instance's authentication
|
|
47
47
|
applies instead, so this switch has no effect there.
|
|
48
|
-
- **Default User**: The ioBroker user whose permissions
|
|
49
|
-
|
|
50
|
-
user
|
|
51
|
-
|
|
48
|
+
- **Default User**: The ioBroker user whose permissions MCP requests run with when authentication is
|
|
49
|
+
disabled (default: `admin`). With authentication enabled, every session runs with the permissions of the
|
|
50
|
+
user who logged in, and this setting is not used. All object/state reads and writes performed by the tools
|
|
51
|
+
are executed in the name of that user, so the user's ACLs are enforced. A plain name like `operator` is
|
|
52
|
+
automatically expanded to `system.user.operator`. As a web extension the host `web` instance's default user
|
|
53
|
+
applies. A session is bound to the user that opened it: requests of another user with the same session id
|
|
54
|
+
are answered with `404 Session not found`.
|
|
52
55
|
- **Enable OAuth**: Offer the browser-based OAuth2 login that MCP clients such as Claude Desktop use when
|
|
53
56
|
a connector is added. In standalone mode this requires *Enable Authentication*. As a **web extension**
|
|
54
57
|
it also works, but the login is then provided by the host `web` instance, so OAuth has to be enabled
|
|
@@ -307,6 +310,13 @@ client calls it and its result is verified:
|
|
|
307
310
|
Placeholder for the next version (at the beginning of the line):
|
|
308
311
|
### **WORK IN PROGRESS**
|
|
309
312
|
-->
|
|
313
|
+
### 1.6.0 (2026-10-24)
|
|
314
|
+
* (@GermanBluefox) With authentication, the tools run with the permissions of the logged-in user instead of the default user; a session can only be used by the user that opened it
|
|
315
|
+
* (@GermanBluefox) As a web extension, the default user of the `web` instance is used
|
|
316
|
+
|
|
317
|
+
### 1.5.1 (2026-10-24)
|
|
318
|
+
* (@GermanBluefox) Transfer folders left behind by a killed process are removed at startup
|
|
319
|
+
|
|
310
320
|
### 1.5.0 (2026-10-24)
|
|
311
321
|
* (@GermanBluefox) Tool results are kept below the 1 MiB limit of MCP clients: lists are paged with `offset`, other results are replaced by a download link
|
|
312
322
|
* (@GermanBluefox) Added download links (`read_file` with `download: true`, complete lists) and upload links (`prepare_upload`, used by `write_file` and `install_package`) for large data (option `transferLinks`)
|
package/build/devices.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* them into an AI-friendly structure of rooms -> devices -> named controls.
|
|
8
8
|
*
|
|
9
9
|
* All object reads accept an optional `{ user }` so the detection respects the ACLs of
|
|
10
|
-
* the
|
|
10
|
+
* the user of the MCP request (see McpServer).
|
|
11
11
|
*/
|
|
12
12
|
import { type ExternalDetectorState, Types } from '@iobroker/type-detector';
|
|
13
13
|
/** Read options passed through to `getObjectViewAsync` (currently only the ACL user). */
|
package/build/devices.js
CHANGED
|
@@ -45,7 +45,7 @@ exports.getAiFriendlyStructure = getAiFriendlyStructure;
|
|
|
45
45
|
* them into an AI-friendly structure of rooms -> devices -> named controls.
|
|
46
46
|
*
|
|
47
47
|
* All object reads accept an optional `{ user }` so the detection respects the ACLs of
|
|
48
|
-
* the
|
|
48
|
+
* the user of the MCP request (see McpServer).
|
|
49
49
|
*/
|
|
50
50
|
const type_detector_1 = __importStar(require("@iobroker/type-detector"));
|
|
51
51
|
/**
|
package/build/index.d.ts
CHANGED
|
@@ -17,8 +17,10 @@ export default class McpServer {
|
|
|
17
17
|
private config;
|
|
18
18
|
private readonly extension;
|
|
19
19
|
private readonly routerPrefix;
|
|
20
|
-
/** The ioBroker user whose permissions
|
|
20
|
+
/** The ioBroker user whose permissions MCP requests run with when no user is logged in. */
|
|
21
21
|
private readonly defaultUser;
|
|
22
|
+
/** The user of the MCP request being processed, set by {@link runAs} for each HTTP request. */
|
|
23
|
+
private readonly requestUser;
|
|
22
24
|
/** Default language used to localize device/room/function names. */
|
|
23
25
|
private readonly language;
|
|
24
26
|
/**
|
|
@@ -149,6 +151,25 @@ export default class McpServer {
|
|
|
149
151
|
order: number;
|
|
150
152
|
pro: boolean;
|
|
151
153
|
};
|
|
154
|
+
/** Normalize a plain user name or a `system.user.*` id to the full id. */
|
|
155
|
+
private static toUserId;
|
|
156
|
+
/**
|
|
157
|
+
* The ioBroker user a request runs as: the logged-in user when the request was authenticated (by
|
|
158
|
+
* us or, as a web extension, by the host `web` instance), otherwise the default user.
|
|
159
|
+
*/
|
|
160
|
+
private getRequestUser;
|
|
161
|
+
/** The user the current tool call runs as. Outside a request (embedded mode) the default user. */
|
|
162
|
+
private get user();
|
|
163
|
+
/**
|
|
164
|
+
* Process a request of a session with the permissions of the session's user. The SDK dispatches the
|
|
165
|
+
* contained messages within this call, so every tool reached from here sees that user in {@link user}.
|
|
166
|
+
*/
|
|
167
|
+
private runAs;
|
|
168
|
+
/**
|
|
169
|
+
* Get the session of a request. A session is bound to the user that opened it: requests of another
|
|
170
|
+
* user are answered like an unknown session, so that a leaked session id gives no access.
|
|
171
|
+
*/
|
|
172
|
+
private getSession;
|
|
152
173
|
/** Handle client -> server messages (initialize, tools/call, ...). */
|
|
153
174
|
private handleMcpPost;
|
|
154
175
|
/** Handle server -> client SSE stream (GET) and session termination (DELETE). */
|
|
@@ -197,12 +218,12 @@ export default class McpServer {
|
|
|
197
218
|
private getStates;
|
|
198
219
|
/**
|
|
199
220
|
* Write multiple states as one operation: the write permission of every state is verified first, so a
|
|
200
|
-
* batch containing a single state the
|
|
221
|
+
* batch containing a single state the user may not write fails as a whole and nothing is
|
|
201
222
|
* written. Other failures of single states are reported per item and do not abort the rest.
|
|
202
223
|
*/
|
|
203
224
|
private setStates;
|
|
204
225
|
/**
|
|
205
|
-
* Verify that the
|
|
226
|
+
* Verify that the user of the request may write every given state, mirroring the checks js-controller runs in
|
|
206
227
|
* `setForeignState`: the user must be able to read the object (needed for the type coercion in
|
|
207
228
|
* {@link setState}) and the state ACL must allow writing — for an alias also on its write target.
|
|
208
229
|
*
|
|
@@ -214,7 +235,7 @@ export default class McpServer {
|
|
|
214
235
|
* The state ACL check of js-controller for `setState` on a single object.
|
|
215
236
|
*
|
|
216
237
|
* @param obj the state object (objects without ACL are not restricted by js-controller)
|
|
217
|
-
* @param permissions the merged group permissions of the
|
|
238
|
+
* @param permissions the merged group permissions of the user
|
|
218
239
|
*/
|
|
219
240
|
private isStateWritable;
|
|
220
241
|
/**
|
|
@@ -395,6 +416,12 @@ export default class McpServer {
|
|
|
395
416
|
* token. The file lives in a temporary folder until the link expires (or the upload is used).
|
|
396
417
|
*/
|
|
397
418
|
private createTransfer;
|
|
419
|
+
/**
|
|
420
|
+
* Remove the transfer folders that a process left behind when it was killed. Other MCP servers on this
|
|
421
|
+
* host (web extension, standalone, admin) use the same temp folder, so only folders unchanged for longer
|
|
422
|
+
* than a link lives are removed: every new link creates a subfolder and so touches its folder.
|
|
423
|
+
*/
|
|
424
|
+
private removeStaleTransferDirs;
|
|
398
425
|
/** The public URL of a download or upload link. */
|
|
399
426
|
private transferUrl;
|
|
400
427
|
/** Remove a link and its file. */
|