@thinger-io/cli 0.0.0-stage → 0.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/CHANGELOG.md ADDED
@@ -0,0 +1,58 @@
1
+ # Changelog
2
+
3
+ ## [0.2.2] - 2026-10-12
4
+
5
+ ### Changed
6
+
7
+ - First release of `@thinger-io/cli` from GitHub Actions (Trusted Publishing,
8
+ with provenance); 0.2.1 was published by hand to create the package.
9
+
10
+ ## [0.2.1] - 2026-10-12
11
+
12
+ ### Changed
13
+
14
+ - Published as `@thinger-io/cli` (formerly `@thinger-io/thinger-cli`, now
15
+ deprecated). The command is still `thinger` and profiles stay in
16
+ `~/.config/thinger-cli`.
17
+
18
+ ## [0.2.0] - 2026-10-10
19
+
20
+ ### Changed
21
+
22
+ - Requires `@thinger-io/cli-core` 0.2.0: the MCP server goes from 48 tools to
23
+ 23 (`thinger_resource_*` over a catalog of resource types, plus the
24
+ operations that are not CRUD), less than half the size in `tools/list`.
25
+ Tool names change: `thinger_devices` → `thinger_resource_list` with
26
+ `type: "device"`, `thinger_profiles` → `thinger_profile_list`,
27
+ `thinger_bucket_read` → `thinger_bucket_data_read`, and so on.
28
+ - MCP instructions rewritten for the new tools.
29
+
30
+
31
+ ## [0.1.1] - 2026-10-10
32
+
33
+ ### Changed
34
+
35
+ - Requires `@thinger-io/cli-core` 0.1.1. First release published from GitHub
36
+ Actions through Trusted Publishing.
37
+
38
+ ## [0.1.0] - 2026-10-10
39
+
40
+ First version: the `thinger` CLI, built on
41
+ [@thinger-io/cli-core](https://github.com/thinger-io/thinger-cli-core) (the generic
42
+ core of ThinRemote's `thinr`, made independent of the product).
43
+
44
+ ### Added
45
+
46
+ - Thinger identity: profiles in `~/.config/thinger-cli`, `THINGER_PROFILE` /
47
+ `THINGER_INSECURE`, MCP tools as `thinger_*`.
48
+ - `login` with username/password (mints the `thinger_cli` API token), an
49
+ existing token (non-interactive with `--server --username --token`) or the
50
+ OAuth device flow with a client registered on the server.
51
+ - `logout` forgets the current profile (or `--all`) and revokes the API token
52
+ the CLI created.
53
+ - Commands: `device` (list, info, create, delete, set-product, property,
54
+ property-set, resource), `product` (list, info, create, delete,
55
+ property-list, property-get, property-set, property-delete), `bucket` (list,
56
+ read), `profile`.
57
+ - `thinger mcp`: devices, resources, properties, products, product profiles,
58
+ buckets, tokens, alarms and profiles.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+
2
+ MIT License
3
+
4
+ Copyright (c) 2025 Thinger.io
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,139 @@
1
- # Temporary Holding Version
1
+ # thinger — Thinger.io CLI
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A command-line tool for any [Thinger.io](https://thinger.io) server, and an
4
+ MCP server that lets AI assistants (Claude Code, Claude Desktop, Cursor…)
5
+ operate it with the permissions of your token.
6
+
7
+ - **CLI** — devices, products, buckets and profiles from a shell, with
8
+ `--json` output for scripts.
9
+ - **MCP server** — `thinger mcp` serves 23 `thinger_*` tools over
10
+ stdio.
11
+
12
+ Both share the same profiles and API layer: sign in once, use either.
13
+
14
+ > Interim tool. The long-term Thinger MCP is built into the server itself;
15
+ > until then this CLI gives every Thinger server an MCP today.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install -g @thinger-io/cli
21
+ # or, from source
22
+ git clone https://github.com/thinger-io/thinger-cli.git && cd thinger-cli && npm install && npm link
23
+ ```
24
+
25
+ Requires Node.js 20 or newer.
26
+
27
+ ## Signing in
28
+
29
+ ```bash
30
+ thinger login # interactive: username/password, token or OAuth
31
+ thinger login --server acme.aws.thinger.io --username alice --token <API token>
32
+ ```
33
+
34
+ - **Username and password** — creates (or replaces) an API token named
35
+ _Thinger CLI_ (id `thinger_cli`) on your account and stores it. `thinger
36
+ logout` revokes it.
37
+ - **Token** — paste an existing API token; it is validated and stored as is.
38
+ - **OAuth** — browser device flow. Needs an OAuth client registered on the
39
+ server (`--client-id`); Thinger servers ship none by default yet.
40
+
41
+ The server is a host (`acme.aws.thinger.io`, HTTPS) or a full URL for plain
42
+ HTTP or custom ports (`http://localhost:8080`). Self-signed certificates are
43
+ accepted for `localhost`, or anywhere with `THINGER_INSECURE=1`.
44
+
45
+ ## Profiles
46
+
47
+ Each profile is a server plus its credentials, stored in
48
+ `~/.config/thinger-cli/config.json` (mode 600).
49
+
50
+ ```bash
51
+ thinger profile add staging # sign in to another server
52
+ thinger profile list
53
+ thinger profile use staging # change the default
54
+ thinger --profile staging device list
55
+ THINGER_PROFILE=staging thinger device list
56
+ ```
57
+
58
+ `-u, --user <account>` addresses another account on the same server when
59
+ your profile has admin rights.
60
+
61
+ ## Commands
62
+
63
+ ```bash
64
+ thinger device list [pattern] # regex on id/name
65
+ thinger device info <id>
66
+ thinger device create <id> [-t Generic|MQTT|HTTP|Virtual|Subdevice] [-p product]
67
+ thinger device delete <id> [-y]
68
+ thinger device set-product <id> <product>
69
+ thinger device property <id> [property] [-f dot.path]
70
+ thinger device property-set <id> <property> <json>
71
+ thinger device resource <id> [resource] [-i key=value …]
72
+
73
+ thinger product list | info <id> | delete <id>
74
+ thinger product create <id> [--from product.json] # { config, profile }
75
+ thinger product property-list <id>
76
+ thinger product property-get <id> <property>
77
+ thinger product property-set <id> <property> <json>
78
+ thinger product property-delete <id> <property>
79
+
80
+ thinger bucket list
81
+ thinger bucket read <bucket> [-d device] [-n 10] [-m minutes] [--agg 5m --agg-type mean]
82
+ ```
83
+
84
+ Every command takes `-j, --json` and then prints `{ ok, data }` or
85
+ `{ ok: false, error: { message, code } }`.
86
+
87
+ ## MCP server
88
+
89
+ ```bash
90
+ claude mcp add thinger -- thinger mcp
91
+ # without installing it: claude mcp add thinger -- npx -y @thinger-io/cli mcp
92
+ # from source: claude mcp add thinger -- node /path/to/thinger-cli/bin/thinger.js mcp
93
+ ```
94
+
95
+ Other hosts take the same command (`thinger`, args `["mcp"]`), or
96
+ `npx` with args `["-y", "@thinger-io/cli", "mcp"]`.
97
+
98
+ Tools:
99
+
100
+ - `thinger_resource_describe`, `_list`, `_get`, `_create`, `_update`,
101
+ `_delete`, `_clone`, `_call` — every server resource by `type`: devices,
102
+ products, buckets, dashboards, endpoints, storages, asset types and
103
+ groups, projects and their members, tokens, alarms, claims, properties,
104
+ their children, and the server's administration (users, hosts, domains,
105
+ brands, OAuth clients, identity providers, proxies). `resource_call` runs
106
+ actions such as verifying a domain, calling an endpoint or testing an
107
+ alarm rule. `resource_describe` shows a type's fields, examples and
108
+ actions, read from the server's own API description.
109
+ - `thinger_bucket_data_read` / `_write`, `thinger_device_resource_list` /
110
+ `_call`, `thinger_device_data_send`, `thinger_device_overview`,
111
+ `thinger_product_resource_call`, `thinger_storage_file_list` / `_read` /
112
+ `_write` / `_delete`, `thinger_dashboard_publish`, `thinger_doc_read`,
113
+ `thinger_profile_list`.
114
+
115
+ Every tool takes an optional `profile`, and most an optional `user`.
116
+
117
+ ## Shared core
118
+
119
+ Everything that is not Thinger-specific — API client, auth, profiles, REST
120
+ helpers, the generic commands and the MCP tools — lives in
121
+ [@thinger-io/cli-core](https://github.com/thinger-io/thinger-cli-core). This CLI only
122
+ supplies its identity (`lib/identity.js`): binary name, config folder,
123
+ environment prefix, the token the password login creates, OAuth client and
124
+ MCP tool prefix. ThinRemote's `thinr` is built on the same core with its own
125
+ identity, so the two keep separate profiles and tool names and can run side
126
+ by side.
127
+
128
+ ## Development
129
+
130
+ ```bash
131
+ npm install
132
+ npm test # node --test
133
+ npm run lint
134
+ npm run typecheck
135
+ ```
136
+
137
+ ## License
138
+
139
+ MIT
package/bin/thinger.js ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync } from 'fs';
4
+ import { fileURLToPath } from 'url';
5
+ import { dirname, resolve } from 'path';
6
+ import { defineIdentity } from '@thinger-io/cli-core/identity';
7
+ import { runCli } from '@thinger-io/cli-core/cli';
8
+ import { mcpInstructions, thingerIdentity } from '../lib/identity.js';
9
+
10
+ // Single source of truth for the version: package.json.
11
+ const pkg = JSON.parse(
12
+ readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), '../package.json'), 'utf8'),
13
+ );
14
+
15
+ defineIdentity(thingerIdentity);
16
+ await runCli({ version: pkg.version, mcpInstructions });
@@ -0,0 +1,36 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * Identity of the `thinger` CLI. This is the only Thinger-specific piece:
5
+ * everything else comes from @thinger-io/cli-core, shared with other CLIs
6
+ * built on it (thinr), which pass their own identity.
7
+ *
8
+ * Profiles live apart from thinr's (~/.config/thinr-cli, THINR_*) on
9
+ * purpose, so neither CLI's MCP server operates on the other's servers.
10
+ *
11
+ * @type {import('@thinger-io/cli-core/identity').CliIdentity}
12
+ */
13
+ export const thingerIdentity = {
14
+ name: 'thinger',
15
+ displayName: 'Thinger.io',
16
+ description:
17
+ 'CLI for Thinger.io servers — devices, products, buckets, with an MCP server for AI clients',
18
+ configDir: 'thinger-cli',
19
+ envPrefix: 'THINGER',
20
+ token: { id: 'thinger_cli', name: 'Thinger CLI' },
21
+ // No OAuth client ships with Thinger servers yet: the browser login asks
22
+ // for one registered on the instance.
23
+ oauth: { clientId: null },
24
+ defaultServer: null,
25
+ mcp: { serverName: 'thinger', toolPrefix: 'thinger' },
26
+ };
27
+
28
+ /** Server-level guidance sent to MCP clients on `initialize`. */
29
+ export const mcpInstructions = `Tools to operate a Thinger.io IoT server with the permissions of the token stored in the CLI profile.
30
+
31
+ - Server resources (devices, products, buckets, dashboards, tokens, alarms, properties…) are reached through thinger_resource_list / _get / _create / _update / _delete / _clone with a \`type\`. Start with thinger_resource_describe without arguments: it lists the types and, on servers that publish it, explains the platform's concepts (which data source fits each need, recipes). With a type it gives its fields and examples: call it before writing one for the first time.
32
+ - List before acting to discover ids (thinger_resource_list with type "device", "product", "bucket"…); never guess them.
33
+ - Device resources (the API a connected device's firmware exposes) are a different thing: thinger_device_resource_list / thinger_device_resource_call.
34
+ - Custom dashboards are HTML apps using the server's dashboard SDK: publish them with thinger_dashboard_publish (thinger_resource_describe type "dashboard" has the SDK reference).
35
+ - Every tool takes an optional \`profile\` (another configured server, see thinger_profile_list) and most take \`user\` (another account, admin only).
36
+ - Destructive tools (delete, overwrite) act immediately: confirm with the user first.`;
package/package.json CHANGED
@@ -1,6 +1,56 @@
1
1
  {
2
- "name": "@thinger-io/cli",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@thinger-io/cli",
3
+ "version": "0.2.2",
4
+ "description": "CLI for Thinger.io servers — devices, products, buckets — with an MCP server for AI clients",
5
+ "main": "bin/thinger.js",
6
+ "bin": {
7
+ "thinger": "bin/thinger.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "lib",
12
+ "CHANGELOG.md",
13
+ "LICENSE",
14
+ "README.md"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/thinger-io/thinger-cli.git"
19
+ },
20
+ "bugs": "https://github.com/thinger-io/thinger-cli/issues",
21
+ "homepage": "https://github.com/thinger-io/thinger-cli#readme",
22
+ "scripts": {
23
+ "start": "node bin/thinger.js",
24
+ "lint": "eslint .",
25
+ "lint:fix": "eslint . --fix",
26
+ "format": "prettier --write .",
27
+ "format:check": "prettier --check .",
28
+ "typecheck": "tsc",
29
+ "test": "node --test 'tests/**/*.test.js'"
30
+ },
31
+ "keywords": [
32
+ "cli",
33
+ "iot",
34
+ "thinger",
35
+ "thinger.io",
36
+ "mcp"
37
+ ],
38
+ "author": "Thinger.io",
39
+ "license": "MIT",
40
+ "dependencies": {
41
+ "@thinger-io/cli-core": "^0.2.0"
42
+ },
43
+ "type": "module",
44
+ "engines": {
45
+ "node": ">=20"
46
+ },
47
+ "devDependencies": {
48
+ "@eslint/js": "^10.0.1",
49
+ "@types/node": "^25.6.0",
50
+ "eslint": "^10.2.0",
51
+ "eslint-config-prettier": "^10.1.8",
52
+ "globals": "^17.5.0",
53
+ "prettier": "^3.8.3",
54
+ "typescript": "^6.0.2"
55
+ }
56
+ }