mc8yp 1.0.3 → 2.0.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/LICENSE +1 -1
- package/README.md +184 -105
- package/dist/{add-BnID18hd.mjs → add-C-dXxz3k.mjs} +1 -4
- package/dist/cli.mjs +122887 -47550
- package/dist/creds-CpDDNTs5.mjs +18 -0
- package/dist/{list-qI93mmZ-.mjs → list-DZcNpiMS.mjs} +2 -5
- package/dist/{remove-B-bSxaTt.mjs → remove-DJHimlMb.mjs} +2 -5
- package/package.json +24 -18
- package/dist/creds-D4yS306d.mjs +0 -21
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|

|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that
|
|
7
|
+
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that gives AI agents full access to the Cumulocity IoT platform through code execution. Instead of exposing dozens of fixed tools, the server provides two code-mode tools — `query` and `execute` — that let the agent write JavaScript to inspect the core OpenAPI spec and call any API endpoint.
|
|
8
8
|
|
|
9
9
|
**Two Deployment Modes:**
|
|
10
10
|
|
|
@@ -15,19 +15,16 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that pr
|
|
|
15
15
|
|
|
16
16
|
### CLI Mode (Local Development & Testing)
|
|
17
17
|
|
|
18
|
-
The CLI mode allows you to run the MCP server locally and connect it to your AI agent (e.g., Claude Desktop). It uses STDIO transport and stores Cumulocity credentials securely in your system's native keyring.
|
|
19
|
-
|
|
20
18
|
```sh
|
|
21
|
-
# Run directly
|
|
19
|
+
# Run directly (recommended)
|
|
22
20
|
pnpm dlx mc8yp
|
|
23
21
|
|
|
22
|
+
# Pick a specific core OpenAPI snapshot for query
|
|
23
|
+
pnpm dlx mc8yp --spec 2025
|
|
24
|
+
|
|
24
25
|
# Or install globally
|
|
25
26
|
npm install -g mc8yp
|
|
26
27
|
mc8yp
|
|
27
|
-
|
|
28
|
-
# Or with pnpm
|
|
29
|
-
pnpm add -g mc8yp
|
|
30
|
-
mc8yp
|
|
31
28
|
```
|
|
32
29
|
|
|
33
30
|
**Credential Storage:**
|
|
@@ -39,22 +36,18 @@ Credentials are stored using your operating system's secure credential manager:
|
|
|
39
36
|
|
|
40
37
|
### Microservice Mode (Production Deployment)
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
**Deployment Steps:**
|
|
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.
|
|
45
40
|
|
|
46
41
|
1. Download the latest release package from [GitHub Releases](https://github.com/schplitt/mc8yp/releases)
|
|
47
|
-
2. Upload the `.zip`
|
|
42
|
+
2. Upload the `.zip` to Cumulocity via **Application Management**
|
|
48
43
|
3. Subscribe to the application in your tenant
|
|
49
44
|
4. The MCP server will be available at: `https://<tenant>.cumulocity.com/service/mc8yp-server/mcp`
|
|
50
45
|
|
|
51
|
-
|
|
46
|
+
No additional credential configuration needed — the microservice uses Cumulocity's built-in service user authentication.
|
|
52
47
|
|
|
53
48
|
## Usage
|
|
54
49
|
|
|
55
|
-
###
|
|
56
|
-
|
|
57
|
-
Before using the CLI, you need to store your Cumulocity credentials securely:
|
|
50
|
+
### Managing Credentials (CLI)
|
|
58
51
|
|
|
59
52
|
```sh
|
|
60
53
|
# Add credentials (prompts for tenant URL, username, password)
|
|
@@ -67,11 +60,28 @@ pnpm dlx mc8yp creds list
|
|
|
67
60
|
pnpm dlx mc8yp creds remove
|
|
68
61
|
```
|
|
69
62
|
|
|
70
|
-
|
|
63
|
+
### Selecting The Core OpenAPI Snapshot (CLI)
|
|
64
|
+
|
|
65
|
+
Use `--spec` or `-s` to choose which bundled core OpenAPI snapshot the `query` tool exposes.
|
|
71
66
|
|
|
72
|
-
|
|
67
|
+
Supported values are `release`, `2026`, `2025`, and `2024`.
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
# Default: latest bundled release snapshot
|
|
71
|
+
mc8yp
|
|
72
|
+
|
|
73
|
+
# Explicitly use the 2025 core OpenAPI snapshot
|
|
74
|
+
mc8yp --spec 2025
|
|
75
|
+
|
|
76
|
+
# Short form
|
|
77
|
+
mc8yp -s 2024
|
|
78
|
+
```
|
|
73
79
|
|
|
74
|
-
|
|
80
|
+
This only affects the `query` tool's OpenAPI view. The `execute` tool still calls the live Cumulocity API of the selected tenant or deployed service environment.
|
|
81
|
+
|
|
82
|
+
### Connecting to AI Agents
|
|
83
|
+
|
|
84
|
+
For Claude Desktop or any MCP client, add to your MCP configuration:
|
|
75
85
|
|
|
76
86
|
```json
|
|
77
87
|
{
|
|
@@ -85,136 +95,205 @@ For local development with Claude Desktop or similar MCP clients, add to your MC
|
|
|
85
95
|
}
|
|
86
96
|
```
|
|
87
97
|
|
|
88
|
-
|
|
98
|
+
With restrictions (see [API Restrictions](#api-restrictions)):
|
|
89
99
|
|
|
90
|
-
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"servers": {
|
|
103
|
+
"mc8yp": {
|
|
104
|
+
"type": "stdio",
|
|
105
|
+
"command": "pnpm",
|
|
106
|
+
"args": ["dlx", "mc8yp", "-r", "/alarm/**", "-r", "DELETE:/inventory/**"]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
91
111
|
|
|
92
|
-
|
|
112
|
+
## Tools & Prompts
|
|
93
113
|
|
|
94
|
-
|
|
95
|
-
- pnpm
|
|
96
|
-
- Access to a Cumulocity IoT tenant
|
|
114
|
+
### Tools
|
|
97
115
|
|
|
98
|
-
|
|
116
|
+
| Tool | Description |
|
|
117
|
+
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| `query` | Search and inspect the bundled Cumulocity core OpenAPI spec by running a JavaScript module. The spec is injected as a top-level `spec` binding. Export the result with `export default`. |
|
|
119
|
+
| `execute` | Execute JavaScript against the live Cumulocity API. Provide an async JavaScript function expression. A top-level `cumulocity` binding provides `cumulocity.request({ method, path, body?, headers? })`. Return the final value from that function. |
|
|
120
|
+
| `list-credentials` | _(CLI mode only)_ List stored credentials from your system keyring. |
|
|
99
121
|
|
|
100
|
-
|
|
101
|
-
# Install dependencies
|
|
102
|
-
pnpm install
|
|
122
|
+
Both code-mode tools run in a sandboxed runtime ([secure-exec](https://github.com/nicepkg/secure-exec)).
|
|
103
123
|
|
|
104
|
-
|
|
105
|
-
|
|
124
|
+
- `query` returns JSON text for easier inspection of OpenAPI data.
|
|
125
|
+
- `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.
|
|
106
126
|
|
|
107
|
-
|
|
108
|
-
pnpm typecheck
|
|
127
|
+
### Execute Input Shape
|
|
109
128
|
|
|
110
|
-
|
|
111
|
-
|
|
129
|
+
The `execute` tool expects an async function expression, not module source with `export default`.
|
|
130
|
+
|
|
131
|
+
Recommended shape:
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
async () => {
|
|
135
|
+
return await cumulocity.request({
|
|
136
|
+
method: 'GET',
|
|
137
|
+
path: '/inventory/managedObjects?pageSize=5',
|
|
138
|
+
})
|
|
139
|
+
}
|
|
112
140
|
```
|
|
113
141
|
|
|
114
|
-
|
|
142
|
+
You can also perform intermediate processing before returning the final value:
|
|
115
143
|
|
|
116
|
-
|
|
144
|
+
```js
|
|
145
|
+
async () => {
|
|
146
|
+
const devices = await cumulocity.request({
|
|
147
|
+
method: 'GET',
|
|
148
|
+
path: '/inventory/managedObjects?pageSize=20&withTotalPages=true',
|
|
149
|
+
})
|
|
117
150
|
|
|
118
|
-
|
|
119
|
-
{
|
|
120
|
-
"servers": {
|
|
121
|
-
"local_mc8yp": {
|
|
122
|
-
"type": "stdio",
|
|
123
|
-
"command": "pnpm",
|
|
124
|
-
"args": [
|
|
125
|
-
"dlx",
|
|
126
|
-
"jiti",
|
|
127
|
-
"/path/to/your/project/src/cli/index.ts"
|
|
128
|
-
]
|
|
129
|
-
}
|
|
130
|
-
}
|
|
151
|
+
return devices.managedObjects?.map((device) => ({ id: device.id, name: device.name }))
|
|
131
152
|
}
|
|
132
153
|
```
|
|
133
154
|
|
|
134
|
-
|
|
155
|
+
### Prompts
|
|
156
|
+
|
|
157
|
+
| Prompt | Description |
|
|
158
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
159
|
+
| `code-mode-guide` | Full reference for the `query` and `execute` tools, including available types, examples, and restriction info for the current connection. |
|
|
160
|
+
|
|
161
|
+
## API Restrictions
|
|
162
|
+
|
|
163
|
+
Restrictions are deny rules that block specific API operations. They can be applied per-connection to limit what an AI agent can access.
|
|
164
|
+
|
|
165
|
+
### Rule Format
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
[METHOD:]<path-pattern>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- **Without a method prefix** — blocks all HTTP methods for matching paths
|
|
172
|
+
- **With a method prefix** — blocks only that method (e.g. `GET:`, `DELETE:`, `POST:`)
|
|
173
|
+
- **Path patterns** support `*` (single segment wildcard) and `**` (recursive wildcard)
|
|
174
|
+
- Query strings and fragments are not allowed in patterns
|
|
135
175
|
|
|
136
|
-
|
|
176
|
+
### Examples
|
|
137
177
|
|
|
138
|
-
|
|
178
|
+
| Rule | Effect |
|
|
179
|
+
| -------------------------------- | --------------------------------------------------- |
|
|
180
|
+
| `/inventory/**` | Block all methods on all inventory paths |
|
|
181
|
+
| `DELETE:/inventory/**` | Block only DELETE on inventory paths |
|
|
182
|
+
| `/alarm/alarms` | Block all methods on the exact path `/alarm/alarms` |
|
|
183
|
+
| `GET:/measurement/measurements` | Block only GET on measurements |
|
|
184
|
+
| `POST:/inventory/managedObjects` | Block creating new managed objects |
|
|
185
|
+
| `/user/**` | Block all user management |
|
|
139
186
|
|
|
140
|
-
|
|
187
|
+
### CLI Mode
|
|
141
188
|
|
|
142
|
-
|
|
189
|
+
Pass restrictions as CLI arguments. Repeat `-r` / `--restriction` for multiple rules:
|
|
143
190
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
- `get-supported-series` - Discover measurement types a device supports
|
|
191
|
+
```sh
|
|
192
|
+
# Block all inventory access
|
|
193
|
+
mc8yp -r "/inventory/**"
|
|
148
194
|
|
|
149
|
-
|
|
195
|
+
# Block deletes on inventory and all alarm access
|
|
196
|
+
mc8yp -r "DELETE:/inventory/**" -r "/alarm/**"
|
|
150
197
|
|
|
151
|
-
|
|
152
|
-
|
|
198
|
+
# Block everything under user management
|
|
199
|
+
mc8yp --restriction "/user/**"
|
|
200
|
+
```
|
|
153
201
|
|
|
154
|
-
|
|
202
|
+
### Microservice Mode (HTTP)
|
|
155
203
|
|
|
156
|
-
|
|
157
|
-
- `get-event-types` - Discover available event types for a device
|
|
204
|
+
Pass restrictions as `restriction` query parameters on the MCP endpoint URL:
|
|
158
205
|
|
|
159
|
-
|
|
206
|
+
```
|
|
207
|
+
/mcp?restriction=/inventory/**&restriction=DELETE:/alarm/**
|
|
208
|
+
```
|
|
160
209
|
|
|
161
|
-
|
|
162
|
-
- `get-alarm-counts` - Get alarm counts grouped by severity
|
|
210
|
+
### How Restrictions Work
|
|
163
211
|
|
|
164
|
-
**
|
|
212
|
+
1. **OpenAPI spec annotation**: The `query` tool annotates blocked operations in the spec with `x-mc8yp-restricted` and related `x-mc8yp-*` metadata fields. The operations remain visible so the agent understands what exists, but they are clearly marked as blocked.
|
|
165
213
|
|
|
166
|
-
|
|
167
|
-
- `get-current-user` - Get current user details
|
|
168
|
-
- `get-users` - List users on the tenant
|
|
169
|
-
- `get-applications` - List available applications
|
|
170
|
-
- `get-application` - Get specific application details
|
|
171
|
-
- `get-application-versions` - Get all versions of an application
|
|
172
|
-
- `get-audit` - Query audit logs
|
|
173
|
-
- `get-tenant-stats` - Get tenant usage statistics
|
|
174
|
-
- `get-tenant-summary` - Get tenant usage summary
|
|
175
|
-
- `get-dashboards` - Get dashboards for a device or group
|
|
214
|
+
2. **Sandbox request enforcement**: The `execute` tool checks restrictions inside the generated sandbox request helper, where the actual HTTP method and normalized path are both available. Matching requests are blocked before any `fetch` is attempted.
|
|
176
215
|
|
|
177
|
-
|
|
216
|
+
3. **Network boundary**: The secure-exec permission layer independently restricts network access to the configured tenant host. Other network operations are denied.
|
|
178
217
|
|
|
179
|
-
|
|
218
|
+
When an `execute` request is blocked by MCP restrictions, the tool returns explanatory text stating that the operation was intentionally denied by MCP connection policy, no request was sent to Cumulocity, and retrying through the same connection will not help.
|
|
180
219
|
|
|
181
|
-
|
|
220
|
+
## Build And Packaging
|
|
182
221
|
|
|
183
|
-
|
|
184
|
-
- Time window guidance for queries
|
|
222
|
+
The repository bundles multiple core OpenAPI snapshots for CLI use and builds one microservice server bundle per snapshot version.
|
|
185
223
|
|
|
186
|
-
|
|
224
|
+
### Build Outputs
|
|
187
225
|
|
|
188
|
-
|
|
189
|
-
- Finding devices by criteria
|
|
190
|
-
- OData query syntax help
|
|
191
|
-
- Device discovery workflows
|
|
226
|
+
`pnpm build` produces:
|
|
192
227
|
|
|
193
|
-
|
|
228
|
+
- CLI bundle in `dist/`
|
|
229
|
+
- Versioned server bundles in `.output/release/`, `.output/2026/`, `.output/2025/`, and `.output/2024/`
|
|
194
230
|
|
|
195
|
-
-
|
|
196
|
-
- Time range calculations
|
|
197
|
-
- Data aggregation guidance
|
|
231
|
+
The versions built are driven by [`openapi-versions.json`](openapi-versions.json). Each server bundle contains only its own `core-openapi/<version>.json` snapshot.
|
|
198
232
|
|
|
199
|
-
|
|
233
|
+
### Release Packaging
|
|
200
234
|
|
|
201
|
-
-
|
|
202
|
-
- Event history querying
|
|
235
|
+
Use the dedicated packaging command after `pnpm build` to create Docker-based Cumulocity release zips:
|
|
203
236
|
|
|
204
|
-
|
|
237
|
+
```sh
|
|
238
|
+
pnpm package:microservices
|
|
239
|
+
```
|
|
205
240
|
|
|
206
|
-
|
|
207
|
-
- Troubleshooting workflows
|
|
241
|
+
That command creates one zip per bundled server variant in the repository root, for example:
|
|
208
242
|
|
|
209
|
-
|
|
243
|
+
- `mc8yp-release-v1.2.3.zip`
|
|
244
|
+
- `mc8yp-2026-v1.2.3.zip`
|
|
245
|
+
- `mc8yp-2025-v1.2.3.zip`
|
|
246
|
+
- `mc8yp-2024-v1.2.3.zip`
|
|
210
247
|
|
|
211
|
-
|
|
248
|
+
The GitHub release workflow uses that packaging command when building tagged releases.
|
|
212
249
|
|
|
213
|
-
|
|
250
|
+
## Development
|
|
214
251
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
-
|
|
252
|
+
### Prerequisites
|
|
253
|
+
|
|
254
|
+
- Node.js ≥22.0.0
|
|
255
|
+
- pnpm
|
|
256
|
+
|
|
257
|
+
### Setup
|
|
258
|
+
|
|
259
|
+
```sh
|
|
260
|
+
pnpm install
|
|
261
|
+
pnpm lint
|
|
262
|
+
pnpm typecheck
|
|
263
|
+
pnpm build
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Testing
|
|
267
|
+
|
|
268
|
+
```sh
|
|
269
|
+
# Run tests
|
|
270
|
+
pnpm test:run
|
|
271
|
+
|
|
272
|
+
# Run benchmarks
|
|
273
|
+
pnpm test:bench
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Run Locally
|
|
277
|
+
|
|
278
|
+
Build first, then point your MCP client at the compiled CLI:
|
|
279
|
+
|
|
280
|
+
```sh
|
|
281
|
+
pnpm build
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Then add to your local MCP client configuration:
|
|
285
|
+
|
|
286
|
+
```json
|
|
287
|
+
{
|
|
288
|
+
"servers": {
|
|
289
|
+
"local_mc8yp": {
|
|
290
|
+
"type": "stdio",
|
|
291
|
+
"command": "node",
|
|
292
|
+
"args": ["/path/to/your/project/dist/cli.mjs"]
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
```
|
|
218
297
|
|
|
219
298
|
## License
|
|
220
299
|
|
|
@@ -3,7 +3,6 @@ import { defineCommand } from "citty";
|
|
|
3
3
|
import consola from "consola";
|
|
4
4
|
import * as v from "valibot";
|
|
5
5
|
import { exit } from "node:process";
|
|
6
|
-
|
|
7
6
|
//#region src/cli/subcommands/subcommands/add.ts
|
|
8
7
|
const command = defineCommand({
|
|
9
8
|
meta: {
|
|
@@ -47,7 +46,5 @@ const command = defineCommand({
|
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
48
|
});
|
|
50
|
-
var add_default = command;
|
|
51
|
-
|
|
52
49
|
//#endregion
|
|
53
|
-
export {
|
|
50
|
+
export { command as default };
|