mc8yp 2.2.0 → 2.2.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/README.md +169 -64
- package/dist/cli.mjs +18 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,19 +1,129 @@
|
|
|
1
|
-
# mc8yp - Cumulocity
|
|
1
|
+
# mc8yp - Full Cumulocity API Access for AI Agents
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|

|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
mc8yp is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that gives AI agents access to the **full Cumulocity API surface** through a compact code-mode interface.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
It supports the two bundled Cumulocity API families exposed by this project:
|
|
10
10
|
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
11
|
+
- **Core API**
|
|
12
|
+
- **DTM API**
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Instead of limiting agents to a small fixed set of prebuilt tools, mc8yp gives them broad access to Cumulocity through two code-mode tools:
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
- `query` — inspect the bundled Core + DTM OpenAPI specs
|
|
17
|
+
- `execute` — call the live Cumulocity API
|
|
18
|
+
|
|
19
|
+
The result is an MCP integration where agents can work across the broader Cumulocity platform, while operators still keep **fine-grained control** over what is actually allowed at runtime.
|
|
20
|
+
|
|
21
|
+
mc8yp is available in two modes:
|
|
22
|
+
|
|
23
|
+
- **Cumulocity microservice mode** for production use with [AI Agent Manager](https://cumulocity.com/docs/ai/aim-introduction/)
|
|
24
|
+
- **CLI mode** for local debugging, testing, and development
|
|
25
|
+
|
|
26
|
+
## Why mc8yp
|
|
27
|
+
|
|
28
|
+
### Full API power for agents
|
|
29
|
+
|
|
30
|
+
mc8yp is built to give agents access to the **complete Cumulocity API surface available through the bundled Core and DTM specs**, instead of a tiny curated subset of actions.
|
|
31
|
+
|
|
32
|
+
That means agents are not blocked just because a specific endpoint was never wrapped as a custom MCP tool.
|
|
33
|
+
|
|
34
|
+
### Built for AI Agent Manager first
|
|
35
|
+
|
|
36
|
+
The primary production deployment model is **Cumulocity microservice mode**.
|
|
37
|
+
|
|
38
|
+
Deploy mc8yp as a Cumulocity microservice and expose `/mcp` to **AI Agent Manager**, so agents can use broad Cumulocity API capabilities inside the platform.
|
|
39
|
+
|
|
40
|
+
### Full power, controlled access
|
|
41
|
+
|
|
42
|
+
Broad capability does **not** have to mean unrestricted access.
|
|
43
|
+
|
|
44
|
+
mc8yp lets you constrain live API usage with:
|
|
45
|
+
|
|
46
|
+
- **restrictions** to deny specific methods or paths
|
|
47
|
+
- **allow rules** to define an allow-list
|
|
48
|
+
- **bundled OpenAPI disablement** for selected API families
|
|
49
|
+
- **sandboxed execution** and a tenant-host network boundary
|
|
50
|
+
- normal **Cumulocity permissions** from the authenticated user or service user
|
|
51
|
+
|
|
52
|
+
This makes setups like these possible:
|
|
53
|
+
|
|
54
|
+
- **read-only agents**
|
|
55
|
+
- **non-destructive production agents**
|
|
56
|
+
- agents limited to **inventory**, **alarms**, or other selected API families
|
|
57
|
+
- agents allowed to write only to a small approved set of endpoints
|
|
58
|
+
|
|
59
|
+
### Token efficiency comes from the small MCP surface
|
|
60
|
+
|
|
61
|
+
The agent gets broad API reach without requiring a huge fixed tool inventory. Instead of many endpoint-specific tools, mc8yp keeps the MCP surface compact and lets the model reason over the bundled OpenAPI specs.
|
|
62
|
+
|
|
63
|
+
## How it works
|
|
64
|
+
|
|
65
|
+
1. The agent uses `query` to inspect the bundled Cumulocity OpenAPI specs.
|
|
66
|
+
2. The agent decides which Core or DTM endpoint it needs.
|
|
67
|
+
3. The agent uses `execute` to call the live Cumulocity API.
|
|
68
|
+
4. mc8yp enforces configured restrictions and allow rules before sending the request.
|
|
69
|
+
|
|
70
|
+
## Deployment Modes
|
|
71
|
+
|
|
72
|
+
### 1. Cumulocity Microservice Mode (recommended)
|
|
73
|
+
|
|
74
|
+
Designed for deployment inside **Cumulocity IoT**.
|
|
75
|
+
|
|
76
|
+
In this mode, mc8yp exposes an HTTP MCP endpoint at `/mcp` and is intended for use with **AI Agent Manager**.
|
|
77
|
+
|
|
78
|
+
- deploy through Cumulocity microservice packaging
|
|
79
|
+
- integrate with [AI Agent Manager](https://cumulocity.com/docs/ai/aim-introduction/)
|
|
80
|
+
- use the service user's permissions automatically
|
|
81
|
+
- configure per-connection MCP policy with restrictions, allow rules, and bundled OpenAPI disablement
|
|
82
|
+
|
|
83
|
+
### 2. CLI Mode (local development)
|
|
84
|
+
|
|
85
|
+
CLI mode is ideal for:
|
|
86
|
+
|
|
87
|
+
- local debugging
|
|
88
|
+
- testing agent prompts and workflows
|
|
89
|
+
- validating access-policy setups before deployment
|
|
90
|
+
- working with MCP clients such as Claude Desktop
|
|
91
|
+
|
|
92
|
+
Credentials are stored in your operating system's secure credential manager.
|
|
93
|
+
|
|
94
|
+
## Quick Start: AI Agent Manager / Microservice
|
|
95
|
+
|
|
96
|
+
1. Download the latest release package from [GitHub Releases](https://github.com/schplitt/mc8yp/releases)
|
|
97
|
+
2. Upload the `.zip` in **Application Management**
|
|
98
|
+
3. Subscribe the application in your tenant
|
|
99
|
+
4. Connect your agent workflow to:
|
|
100
|
+
|
|
101
|
+
```txt
|
|
102
|
+
https://<tenant>.cumulocity.com/service/mc8yp-server/mcp
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
No extra tenant credential setup is required in microservice mode. The microservice uses Cumulocity's deployment environment and request authentication model.
|
|
106
|
+
|
|
107
|
+
### Example: production-safe read-only microservice connection
|
|
108
|
+
|
|
109
|
+
You can expose broad API knowledge to the agent while allowing only safe read access at runtime.
|
|
110
|
+
|
|
111
|
+
Example MCP endpoint configuration patterns:
|
|
112
|
+
|
|
113
|
+
```txt
|
|
114
|
+
/mcp?allow=GET:/inventory/**&allow=GET:/alarm/**&allow=GET:/measurement/**
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Or with headers:
|
|
118
|
+
|
|
119
|
+
```http
|
|
120
|
+
POST /mcp HTTP/1.1
|
|
121
|
+
mc8yp-allow: GET:/inventory/**
|
|
122
|
+
mc8yp-allow: GET:/alarm/**
|
|
123
|
+
mc8yp-allow: GET:/measurement/**
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Quick Start: Local CLI
|
|
17
127
|
|
|
18
128
|
```sh
|
|
19
129
|
# Run directly (recommended)
|
|
@@ -27,27 +137,15 @@ npm install -g mc8yp
|
|
|
27
137
|
mc8yp
|
|
28
138
|
```
|
|
29
139
|
|
|
30
|
-
|
|
31
|
-
|
|
140
|
+
### Credential Storage
|
|
141
|
+
|
|
142
|
+
The interactive `mc8yp creds add` flow uses masked password input and stores credentials in your operating system's secure credential manager.
|
|
32
143
|
|
|
33
144
|
- **macOS**: Keychain
|
|
34
145
|
- **Windows**: Credential Vault
|
|
35
146
|
- **Linux**: Secret Service API (libsecret)
|
|
36
147
|
|
|
37
|
-
###
|
|
38
|
-
|
|
39
|
-
Designed **exclusively for deployment on Cumulocity IoT**. The server exposes an HTTP endpoint at `/mcp` that integrates with Cumulocity's agents manager, automatically using the service user's credentials and permissions.
|
|
40
|
-
|
|
41
|
-
1. Download the latest release package from [GitHub Releases](https://github.com/schplitt/mc8yp/releases)
|
|
42
|
-
2. Upload the `.zip` to Cumulocity via **Application Management**
|
|
43
|
-
3. Subscribe to the application in your tenant
|
|
44
|
-
4. The MCP server will be available at: `https://<tenant>.cumulocity.com/service/mc8yp-server/mcp`
|
|
45
|
-
|
|
46
|
-
No additional credential configuration needed — the microservice uses Cumulocity's built-in service user authentication.
|
|
47
|
-
|
|
48
|
-
## Usage
|
|
49
|
-
|
|
50
|
-
### Managing Credentials (CLI)
|
|
148
|
+
### Managing Credentials
|
|
51
149
|
|
|
52
150
|
```sh
|
|
53
151
|
# Add credentials (prompts for tenant URL, username, and a masked password)
|
|
@@ -56,39 +154,13 @@ pnpm dlx mc8yp creds add
|
|
|
56
154
|
# List stored credentials
|
|
57
155
|
pnpm dlx mc8yp creds list
|
|
58
156
|
|
|
59
|
-
# Remove credentials
|
|
157
|
+
# Remove stored credentials
|
|
60
158
|
pnpm dlx mc8yp creds remove
|
|
61
159
|
```
|
|
62
160
|
|
|
63
|
-
###
|
|
64
|
-
|
|
65
|
-
Use `--spec` or `-s` to choose which bundled **core** OpenAPI snapshot the `query` tool exposes.
|
|
66
|
-
|
|
67
|
-
Supported values are `release`, `2026`, `2025`, and `2024`.
|
|
68
|
-
|
|
69
|
-
This flag selects the bundled **core** API version only. The bundled **dtm** OpenAPI snapshot is currently fixed and is included alongside every supported core build.
|
|
70
|
-
|
|
71
|
-
Each bundled CLI build currently contains:
|
|
72
|
-
|
|
73
|
-
- the selected bundled **core** OpenAPI snapshot
|
|
74
|
-
- the bundled **dtm** OpenAPI snapshot
|
|
75
|
-
|
|
76
|
-
```sh
|
|
77
|
-
# Default: latest bundled release build
|
|
78
|
-
mc8yp
|
|
79
|
-
|
|
80
|
-
# Explicitly use the 2025 bundled build
|
|
81
|
-
mc8yp --spec 2025
|
|
82
|
-
|
|
83
|
-
# Short form
|
|
84
|
-
mc8yp -s 2024
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
This only affects the bundled OpenAPI data that `query` sees. The `execute` tool still calls the live Cumulocity API of the selected tenant or deployed service environment.
|
|
161
|
+
### Connecting a Local MCP Client
|
|
88
162
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
For Claude Desktop or any MCP client, add to your MCP configuration:
|
|
163
|
+
For Claude Desktop or any MCP client, add:
|
|
92
164
|
|
|
93
165
|
```json
|
|
94
166
|
{
|
|
@@ -102,7 +174,7 @@ For Claude Desktop or any MCP client, add to your MCP configuration:
|
|
|
102
174
|
}
|
|
103
175
|
```
|
|
104
176
|
|
|
105
|
-
|
|
177
|
+
Example with read-only access rules:
|
|
106
178
|
|
|
107
179
|
```json
|
|
108
180
|
{
|
|
@@ -110,12 +182,43 @@ With restrictions (see [API Restrictions](#api-restrictions)):
|
|
|
110
182
|
"mc8yp": {
|
|
111
183
|
"type": "stdio",
|
|
112
184
|
"command": "pnpm",
|
|
113
|
-
"args": [
|
|
185
|
+
"args": [
|
|
186
|
+
"dlx",
|
|
187
|
+
"mc8yp",
|
|
188
|
+
"-a",
|
|
189
|
+
"GET:/inventory/**",
|
|
190
|
+
"-a",
|
|
191
|
+
"GET:/alarm/**",
|
|
192
|
+
"-a",
|
|
193
|
+
"GET:/measurement/**"
|
|
194
|
+
]
|
|
114
195
|
}
|
|
115
196
|
}
|
|
116
197
|
}
|
|
117
198
|
```
|
|
118
199
|
|
|
200
|
+
## Bundled OpenAPI Coverage
|
|
201
|
+
|
|
202
|
+
The `query` tool exposes the bundled OpenAPI snapshots included by this project:
|
|
203
|
+
|
|
204
|
+
- **Core** snapshots: `release`, `2026`, `2025`, and `2024`
|
|
205
|
+
- **DTM** snapshot: bundled alongside each supported core build
|
|
206
|
+
|
|
207
|
+
In CLI mode, use `--spec` or `-s` to choose which bundled **core** OpenAPI snapshot `query` exposes:
|
|
208
|
+
|
|
209
|
+
```sh
|
|
210
|
+
# Default: latest bundled release build
|
|
211
|
+
mc8yp
|
|
212
|
+
|
|
213
|
+
# Explicitly use the 2025 bundled build
|
|
214
|
+
mc8yp --spec 2025
|
|
215
|
+
|
|
216
|
+
# Short form
|
|
217
|
+
mc8yp -s 2024
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
This only changes the bundled OpenAPI data that `query` sees. The `execute` tool still calls the live Cumulocity API of the selected tenant or deployed service environment.
|
|
221
|
+
|
|
119
222
|
## Tools & Prompts
|
|
120
223
|
|
|
121
224
|
### Tools
|
|
@@ -131,7 +234,13 @@ Both code-mode tools run in a sandboxed runtime ([secure-exec](https://github.co
|
|
|
131
234
|
- `query` returns JSON text for easier inspection of OpenAPI data.
|
|
132
235
|
- `execute` returns the successful function result in [Toon format](https://github.com/nicepkg/toon). If execution is blocked or fails, it returns a plain text message instead.
|
|
133
236
|
|
|
134
|
-
###
|
|
237
|
+
### Prompts
|
|
238
|
+
|
|
239
|
+
| Prompt | Description |
|
|
240
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
241
|
+
| `code-mode-guide` | Full reference for the `query` and `execute` tools, including available types, examples, and access-policy info for the current connection. |
|
|
242
|
+
|
|
243
|
+
## Execute Input Shape
|
|
135
244
|
|
|
136
245
|
The `execute` tool expects an async function expression, not module source with `export default`.
|
|
137
246
|
|
|
@@ -159,12 +268,6 @@ async () => {
|
|
|
159
268
|
}
|
|
160
269
|
```
|
|
161
270
|
|
|
162
|
-
### Prompts
|
|
163
|
-
|
|
164
|
-
| Prompt | Description |
|
|
165
|
-
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
166
|
-
| `code-mode-guide` | Full reference for the `query` and `execute` tools, including available types, examples, and access-policy info for the current connection. |
|
|
167
|
-
|
|
168
271
|
## API Access Policy
|
|
169
272
|
|
|
170
273
|
mc8yp supports two per-connection rule types:
|
|
@@ -174,6 +277,8 @@ mc8yp supports two per-connection rule types:
|
|
|
174
277
|
|
|
175
278
|
If both apply to the same operation, **restrictions take priority**.
|
|
176
279
|
|
|
280
|
+
This is what makes it possible to expose broad API capability while still keeping an agent in a **read-only** or otherwise **non-destructive** operating mode.
|
|
281
|
+
|
|
177
282
|
Example: allowing `/inventory/**` but restricting `/inventory/managedObjects` still blocks `/inventory/managedObjects`.
|
|
178
283
|
|
|
179
284
|
Both rule types use the same syntax.
|
|
@@ -244,7 +349,7 @@ Supported wildcards:
|
|
|
244
349
|
- `/inventory/**` already matches `/inventory` itself, so you do **not** need both `/inventory` and `/inventory/**`
|
|
245
350
|
- `/i**` is **not valid** because `**` must be its own segment. Use `/i*/**` if you want to match a first segment starting with `i` and everything below it
|
|
246
351
|
- `*:/inventory/**` is allowed and means the same thing as `/inventory/**`
|
|
247
|
-
- Root paths across the bundled
|
|
352
|
+
- Root paths across the bundled Core and DTM specs are intentionally treated as disjoint, so path-based restriction and allow rules are enough for request enforcement
|
|
248
353
|
- Rule patterns may not contain empty segments (`//`), `.` or `..` segments, query strings, or fragments
|
|
249
354
|
|
|
250
355
|
### CLI Mode
|
|
@@ -300,7 +405,7 @@ You can also send project-scoped HTTP headers to avoid conflicts with well-known
|
|
|
300
405
|
|
|
301
406
|
Both headers accept either repeated header instances or a comma-separated list of values. Query parameters and headers can be combined on the same connection.
|
|
302
407
|
|
|
303
|
-
```
|
|
408
|
+
```txt
|
|
304
409
|
/mcp?restriction=/inventory/**&restrict=DELETE:/alarm/**
|
|
305
410
|
/mcp?r=/inventory/**&r=DELETE:/alarm/**
|
|
306
411
|
/mcp?allow=/inventory/**&allowed=POST:/alarm/**
|
|
@@ -389,7 +494,7 @@ pnpm test:run
|
|
|
389
494
|
pnpm test:bench
|
|
390
495
|
```
|
|
391
496
|
|
|
392
|
-
### Run Locally
|
|
497
|
+
### Run Locally From Source
|
|
393
498
|
|
|
394
499
|
Build first, then point your MCP client at the compiled CLI:
|
|
395
500
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import { createRequire } from "node:module";
|
|
2
3
|
import { StdioTransport } from "@tmcp/transport-stdio";
|
|
3
4
|
import { defineCommand, runMain } from "citty";
|
|
@@ -40,7 +41,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
40
41
|
//#endregion
|
|
41
42
|
//#region package.json
|
|
42
43
|
var name = "mc8yp";
|
|
43
|
-
var version = "2.2.
|
|
44
|
+
var version = "2.2.2";
|
|
44
45
|
var description = "Cumulocity IoT MCP Server - Model Context Protocol integration for IoT device management";
|
|
45
46
|
//#endregion
|
|
46
47
|
//#region \0virtual:core-openapi
|
|
@@ -7199,7 +7200,7 @@ const specs$1 = Object.freeze([
|
|
|
7199
7200
|
"password": {
|
|
7200
7201
|
"format": "password",
|
|
7201
7202
|
"type": "string",
|
|
7202
|
-
"description": "The user's password.
|
|
7203
|
+
"description": "The user's password. Allowed characters are: Latin letters (a–z, A–Z), digits (0–9), and the following special characters: ` ~ ! @ # $ % ^ & * ( ) _ | + - = ? ; : ' \" , . < > { } [ ] \\ /\nThe password can only be updated for the current user.\n"
|
|
7203
7204
|
},
|
|
7204
7205
|
"email": {
|
|
7205
7206
|
"type": "string",
|
|
@@ -16376,7 +16377,7 @@ const specs$1 = Object.freeze([
|
|
|
16376
16377
|
"readOnly": true
|
|
16377
16378
|
},
|
|
16378
16379
|
"password": {
|
|
16379
|
-
"description": "The user's password.
|
|
16380
|
+
"description": "The user's password. Allowed characters are: Latin letters (a–z, A–Z), digits (0–9), and the following special characters: ` ~ ! @ # $ % ^ & * ( ) _ | + - = ? ; : ' \" , . < > { } [ ] \\ /",
|
|
16380
16381
|
"type": "string",
|
|
16381
16382
|
"format": "password",
|
|
16382
16383
|
"writeOnly": true,
|
|
@@ -18078,7 +18079,7 @@ const specs$1 = Object.freeze([
|
|
|
18078
18079
|
"readOnly": true
|
|
18079
18080
|
},
|
|
18080
18081
|
"password": {
|
|
18081
|
-
"description": "The user's password.
|
|
18082
|
+
"description": "The user's password. Allowed characters are: Latin letters (a–z, A–Z), digits (0–9), and the following special characters: ` ~ ! @ # $ % ^ & * ( ) _ | + - = ? ; : ' \" , . < > { } [ ] \\ /\n\nIf you do not specify a password when creating a new user with a POST request, it must contain the property `sendPasswordResetEmail` with a value of `true`.\n",
|
|
18082
18083
|
"type": "string",
|
|
18083
18084
|
"format": "password",
|
|
18084
18085
|
"writeOnly": true,
|
|
@@ -93138,8 +93139,9 @@ You have exactly two MCP tools available.
|
|
|
93138
93139
|
## query
|
|
93139
93140
|
Use \`query\` when you need to inspect the bundled OpenAPI specs.
|
|
93140
93141
|
|
|
93141
|
-
- Input: a JavaScript function expression
|
|
93142
|
-
-
|
|
93142
|
+
- Input: a **zero-parameter** JavaScript function expression
|
|
93143
|
+
- Do NOT declare \`coreSpec\`, \`dtmSpec\`, or \`specsEnabled\` as function parameters — they are already declared as top-level constants in the surrounding scope. Writing \`(dtmSpec) => ...\` would shadow the global with an undefined parameter and produce incorrect results
|
|
93144
|
+
- The top-level bindings \`coreSpec\`, \`dtmSpec\`, and \`specsEnabled\` are available automatically inside the function body
|
|
93143
93145
|
- \`coreSpec\` is for the main Cumulocity REST surface such as inventory, alarms, events, measurements, identity, device control, users, tenants, audit, and the broader platform APIs
|
|
93144
93146
|
- \`dtmSpec\` is for Digital Twin Manager work such as schema definitions, asset models, linked series, and DTM asset or definition APIs
|
|
93145
93147
|
- Return the exact value you want back from that function
|
|
@@ -93149,6 +93151,9 @@ Use \`query\` when you need to inspect the bundled OpenAPI specs.
|
|
|
93149
93151
|
- The current MCP connection may still block \`execute\` requests through deny rules and/or an allow list even when an operation exists in a visible spec
|
|
93150
93152
|
|
|
93151
93153
|
### Available Shape
|
|
93154
|
+
|
|
93155
|
+
The function must accept **no parameters**. The bindings below are scope-level constants, not function arguments.
|
|
93156
|
+
|
|
93152
93157
|
\`\`\`ts
|
|
93153
93158
|
type OperationInfo = {
|
|
93154
93159
|
summary?: string
|
|
@@ -93185,7 +93190,7 @@ declare const dtmSpec: DtmSpec
|
|
|
93185
93190
|
declare const specsEnabled: SpecsEnabled
|
|
93186
93191
|
\`\`\`
|
|
93187
93192
|
|
|
93188
|
-
Examples:
|
|
93193
|
+
Examples (all zero-parameter — note no arguments in the arrow function signatures):
|
|
93189
93194
|
\`\`\`js
|
|
93190
93195
|
() => specsEnabled
|
|
93191
93196
|
\`\`\`
|
|
@@ -93196,6 +93201,7 @@ Examples:
|
|
|
93196
93201
|
|
|
93197
93202
|
\`\`\`js
|
|
93198
93203
|
() => {
|
|
93204
|
+
// dtmSpec is already in scope — do NOT write (dtmSpec) => { ... }
|
|
93199
93205
|
const op = dtmSpec.paths['/assets']?.get
|
|
93200
93206
|
return op?.parameters
|
|
93201
93207
|
}
|
|
@@ -150866,7 +150872,9 @@ declare const coreSpec: CoreSpec
|
|
|
150866
150872
|
declare const dtmSpec: DtmSpec
|
|
150867
150873
|
declare const specsEnabled: SpecsEnabled
|
|
150868
150874
|
|
|
150869
|
-
Your code must evaluate to a function.
|
|
150875
|
+
Your code must evaluate to a **zero-parameter** function — do NOT declare \`coreSpec\`, \`dtmSpec\`, or \`specsEnabled\` as function parameters. These are already declared as constants in the surrounding scope and are available inside the function body without any argument passing. Writing \`(dtmSpec) => ...\` would shadow the global binding with an undefined parameter and produce incorrect results.
|
|
150876
|
+
|
|
150877
|
+
The top-level bindings \
|
|
150870
150878
|
|
|
150871
150879
|
a) \`coreSpec\` — use this for the main Cumulocity REST APIs such as inventory, alarms, events, measurements, identity, device control, users, tenants, audit, and the broader platform REST surface
|
|
150872
150880
|
\nb) \`dtmSpec\` — use this for Digital Twin Manager work such as schema definitions, asset models, linked series, and DTM asset or definition APIs
|
|
@@ -150874,7 +150882,7 @@ a) \`coreSpec\` — use this for the main Cumulocity REST APIs such as inventory
|
|
|
150874
150882
|
|
|
150875
150883
|
are available automatically. The sandbox assigns your function to a local variable, invokes it, and returns its result.
|
|
150876
150884
|
|
|
150877
|
-
Recommended shapes:
|
|
150885
|
+
Recommended shapes (zero parameters — bindings come from scope, not arguments):
|
|
150878
150886
|
\`(() => { ... })\`
|
|
150879
150887
|
\`async () => { ... }\`
|
|
150880
150888
|
|
|
@@ -150909,7 +150917,7 @@ Examples:
|
|
|
150909
150917
|
return { summary: op?.summary, parameters: op?.parameters, responses: op?.responses }
|
|
150910
150918
|
}
|
|
150911
150919
|
`,
|
|
150912
|
-
schema: v.object({ code: createCodeSchema("A JavaScript function expression.
|
|
150920
|
+
schema: v.object({ code: createCodeSchema("A zero-parameter JavaScript function expression. Do NOT declare `coreSpec`, `dtmSpec`, or `specsEnabled` as function parameters — they are already declared as top-level constants in the surrounding scope and are available in the function body automatically. Writing `(dtmSpec) => ...` would shadow the global binding with an undefined parameter and produce incorrect results. Return the final result from that function. Async functions are supported.") })
|
|
150913
150921
|
}, async (input) => {
|
|
150914
150922
|
try {
|
|
150915
150923
|
return tool.text(await query(input.code, server.ctx.custom?.restrictions ?? [], server.ctx.custom?.allowRules ?? [], server.ctx.custom?.disabledApis ?? []));
|