thingd-cli 0.5.0 → 0.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 +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/install.d.ts +3 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +98 -0
- package/dist/mcp/tools.js +12 -12
- package/dist/mcp-http.d.ts.map +1 -1
- package/dist/mcp-http.js +5 -1
- package/dist/paths.d.ts +4 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +14 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -20,6 +20,20 @@ Or run it on the fly using `npx`:
|
|
|
20
20
|
npx thingd-cli
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
## Quick Start: Zero-Config MCP Setup
|
|
24
|
+
|
|
25
|
+
The easiest way to integrate `thingd` with your AI editors (Claude Desktop and Cursor) is to run the automated setup command:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
thingd install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This command will:
|
|
32
|
+
- Auto-detect the absolute path of your active `node` binary and global `thingd` script.
|
|
33
|
+
- Automatically locate or create your persistent local database at `~/.thingd/data.db`.
|
|
34
|
+
- **For Claude Desktop**: Automatically configure the stdio MCP server in your `claude_desktop_config.json` (macOS).
|
|
35
|
+
- **For Cursor**: Print the exact, copy-pasteable JSON block to paste into your Cursor MCP settings.
|
|
36
|
+
|
|
23
37
|
## Two Modes of Operation
|
|
24
38
|
|
|
25
39
|
The CLI is designed to support both human operators and automated scripts through two distinct modes:
|
|
@@ -71,7 +85,7 @@ You can configure the connection via environment variables or CLI flags:
|
|
|
71
85
|
```txt
|
|
72
86
|
--url <url> remote thingd URL. Defaults to THINGD_URL
|
|
73
87
|
--auth-token <tok> remote bearer token. Defaults to THINGD_AUTH_TOKEN
|
|
74
|
-
--path <path> local database path. Defaults to THINGD_PATH or
|
|
88
|
+
--path <path> local database path. Defaults to THINGD_PATH or ~/.thingd/data.db
|
|
75
89
|
--driver <driver> memory, native, or cloud
|
|
76
90
|
--pretty pretty-print JSON output
|
|
77
91
|
--limit <n> result limit for search and list commands
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAKA,OAAO,EAOL,MAAM,EACN,KAAK,YAAY,EAClB,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAKA,OAAO,EAOL,MAAM,EACN,KAAK,YAAY,EAClB,MAAM,QAAQ,CAAC;AAKhB,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjD,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AA0CF,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAiCjB;AA+UD,wBAAsB,MAAM,CAC1B,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAcf;AA4BD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,iBAAiB,CAiBxE"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/
|
|
|
5
5
|
import { ThingD, } from "thingd";
|
|
6
6
|
import { runInteractiveCli } from "./interactive.js";
|
|
7
7
|
import { runMcp } from "./mcp.js";
|
|
8
|
+
import { defaultThingdDbPath, ensureThingdDir } from "./paths.js";
|
|
8
9
|
const HELP_TEXT = `thingd
|
|
9
10
|
|
|
10
11
|
Admin and operator CLI for thingd.
|
|
@@ -12,6 +13,7 @@ Admin and operator CLI for thingd.
|
|
|
12
13
|
Usage:
|
|
13
14
|
thingd status [--url <url>]
|
|
14
15
|
thingd tools --url <url>
|
|
16
|
+
thingd install
|
|
15
17
|
thingd mcp [--path <path>] [--driver <driver>]
|
|
16
18
|
thingd mcp-http [--path <path>] [--driver <driver>] [--host <host>] [--port <port>] [--auth-token <tok>] [--allow-unauthenticated]
|
|
17
19
|
thingd search <query> [--collection <name>] [--limit <n>]
|
|
@@ -35,7 +37,7 @@ Usage:
|
|
|
35
37
|
Options:
|
|
36
38
|
--url <url> remote thingd URL. Defaults to THINGD_URL
|
|
37
39
|
--auth-token <tok> remote bearer token. Defaults to THINGD_AUTH_TOKEN
|
|
38
|
-
--path <path> local database path. Defaults to THINGD_PATH or
|
|
40
|
+
--path <path> local database path. Defaults to THINGD_PATH or ~/.thingd/data.db
|
|
39
41
|
--driver <driver> memory, native, or cloud
|
|
40
42
|
--pretty pretty-print JSON output
|
|
41
43
|
--limit <n> result limit for search and list commands
|
|
@@ -93,6 +95,11 @@ async function runCommand(context) {
|
|
|
93
95
|
await runMcpHttp(context);
|
|
94
96
|
return;
|
|
95
97
|
}
|
|
98
|
+
if (command === "install") {
|
|
99
|
+
const { runInstall } = await import("./install.js");
|
|
100
|
+
await runInstall(context);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
96
103
|
if (command === "objects") {
|
|
97
104
|
await runObjects(context);
|
|
98
105
|
return;
|
|
@@ -350,9 +357,12 @@ function buildMemoryEvent(parsed, type) {
|
|
|
350
357
|
}
|
|
351
358
|
export function resolveConnection(context) {
|
|
352
359
|
const url = stringFlag(context.parsed, "url") ?? context.env.THINGD_URL;
|
|
353
|
-
const path = url ?? stringFlag(context.parsed, "path") ?? context.env.THINGD_PATH ??
|
|
360
|
+
const path = url ?? stringFlag(context.parsed, "path") ?? context.env.THINGD_PATH ?? defaultThingdDbPath();
|
|
354
361
|
const cloud = isCloudPath(path);
|
|
355
362
|
const driver = parseDriver(stringFlag(context.parsed, "driver") ?? context.env.THINGD_DRIVER);
|
|
363
|
+
if (!cloud && path === defaultThingdDbPath()) {
|
|
364
|
+
ensureThingdDir();
|
|
365
|
+
}
|
|
356
366
|
return {
|
|
357
367
|
path,
|
|
358
368
|
driver: driver ?? (cloud ? "cloud" : undefined),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAY7C,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCnE"}
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir, platform } from "node:os";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
import { defaultThingdDbPath, ensureThingdDir } from "./paths.js";
|
|
6
|
+
export async function runInstall(context) {
|
|
7
|
+
const nodePath = process.execPath;
|
|
8
|
+
const cliPath = resolveCliPath();
|
|
9
|
+
const dbPath = defaultThingdDbPath();
|
|
10
|
+
const driver = detectDriver();
|
|
11
|
+
ensureThingdDir();
|
|
12
|
+
const config = generateMcpConfig(nodePath, cliPath, dbPath, driver);
|
|
13
|
+
context.stderr.write(`\n${pc.bold("thingd install")}\n\n`);
|
|
14
|
+
context.stderr.write(` ${pc.green("✓")} Database path: ${pc.cyan(dbPath)}\n`);
|
|
15
|
+
context.stderr.write(` ${pc.green("✓")} Driver: ${pc.cyan(driver)}\n`);
|
|
16
|
+
context.stderr.write(` ${pc.green("✓")} Node: ${pc.cyan(nodePath)}\n`);
|
|
17
|
+
context.stderr.write(` ${pc.green("✓")} CLI: ${pc.cyan(cliPath)}\n\n`);
|
|
18
|
+
const claudeResult = updateClaudeDesktopConfig(config);
|
|
19
|
+
if (claudeResult.updated) {
|
|
20
|
+
context.stderr.write(` ${pc.bold("Claude Desktop:")}\n`);
|
|
21
|
+
context.stderr.write(` ${pc.green("✓")} Updated ${pc.cyan(claudeResult.path)}\n\n`);
|
|
22
|
+
}
|
|
23
|
+
else if (claudeResult.skipped) {
|
|
24
|
+
context.stderr.write(` ${pc.bold("Claude Desktop:")}\n`);
|
|
25
|
+
context.stderr.write(` ${pc.yellow("⊘")} Skipped: ${claudeResult.reason}\n\n`);
|
|
26
|
+
}
|
|
27
|
+
context.stderr.write(` ${pc.bold("Cursor:")}\n`);
|
|
28
|
+
context.stderr.write(` Paste this into Cursor Settings → Features → MCP → Add New MCP Server:\n\n`);
|
|
29
|
+
const fullConfig = {
|
|
30
|
+
mcpServers: {
|
|
31
|
+
thingd: config,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
context.stdout.write(`${JSON.stringify(fullConfig, null, 2)}\n`);
|
|
35
|
+
context.stderr.write(`\n Restart Claude Desktop to activate. Cursor activates immediately after pasting.\n\n`);
|
|
36
|
+
}
|
|
37
|
+
function resolveCliPath() {
|
|
38
|
+
const scriptPath = process.argv[1];
|
|
39
|
+
if (!scriptPath) {
|
|
40
|
+
throw new Error("Could not detect thingd CLI path from process.argv[1].");
|
|
41
|
+
}
|
|
42
|
+
return resolve(scriptPath);
|
|
43
|
+
}
|
|
44
|
+
function detectDriver() {
|
|
45
|
+
try {
|
|
46
|
+
// Check if the native .node binary exists relative to the CLI entry point.
|
|
47
|
+
// When installed globally via npm, thingd-native is typically a sibling package.
|
|
48
|
+
const cliDir = join(resolveCliPath(), "..", "..");
|
|
49
|
+
const nativePaths = [
|
|
50
|
+
join(cliDir, "node_modules", "thingd-native", "dist", "thingd_native.node"),
|
|
51
|
+
join(cliDir, "..", "thingd-native", "dist", "thingd_native.node"),
|
|
52
|
+
];
|
|
53
|
+
for (const candidate of nativePaths) {
|
|
54
|
+
if (existsSync(candidate)) {
|
|
55
|
+
return "native";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Ignore detection errors.
|
|
61
|
+
}
|
|
62
|
+
// Default to native since most global installs will have it.
|
|
63
|
+
// If it's not available, the SDK will produce a clear error at open time.
|
|
64
|
+
return "native";
|
|
65
|
+
}
|
|
66
|
+
function generateMcpConfig(nodePath, cliPath, dbPath, driver) {
|
|
67
|
+
return {
|
|
68
|
+
command: nodePath,
|
|
69
|
+
args: [cliPath, "mcp", "--path", dbPath, "--driver", driver],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function updateClaudeDesktopConfig(config) {
|
|
73
|
+
if (platform() !== "darwin") {
|
|
74
|
+
return { skipped: true, reason: "Claude Desktop auto-config is only supported on macOS." };
|
|
75
|
+
}
|
|
76
|
+
const configPath = join(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
77
|
+
if (!existsSync(configPath)) {
|
|
78
|
+
return {
|
|
79
|
+
skipped: true,
|
|
80
|
+
reason: `Config file not found at ${configPath}. Is Claude Desktop installed?`,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
85
|
+
const existing = JSON.parse(raw);
|
|
86
|
+
const mcpServers = (existing.mcpServers ?? {});
|
|
87
|
+
mcpServers.thingd = config;
|
|
88
|
+
existing.mcpServers = mcpServers;
|
|
89
|
+
writeFileSync(configPath, `${JSON.stringify(existing, null, 2)}\n`, "utf-8");
|
|
90
|
+
return { updated: true, path: configPath };
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return {
|
|
94
|
+
skipped: true,
|
|
95
|
+
reason: `Failed to update config: ${error instanceof Error ? error.message : String(error)}`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
package/dist/mcp/tools.js
CHANGED
|
@@ -10,7 +10,7 @@ const auditInputSchema = {
|
|
|
10
10
|
};
|
|
11
11
|
export function registerThingdTools(server, db, options = {}) {
|
|
12
12
|
const audit = resolveThingdMcpAuditOptions(options.audit);
|
|
13
|
-
server.registerTool("
|
|
13
|
+
server.registerTool("thing_search", {
|
|
14
14
|
title: "Search Memory",
|
|
15
15
|
description: "Search thingd objects and events by text.",
|
|
16
16
|
inputSchema: {
|
|
@@ -25,7 +25,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
25
25
|
openWorldHint: false,
|
|
26
26
|
},
|
|
27
27
|
}, async ({ query, collections, limit }) => jsonResult(await db.search(query, { collections, limit })));
|
|
28
|
-
server.registerTool("
|
|
28
|
+
server.registerTool("thing_get", {
|
|
29
29
|
title: "Get Object",
|
|
30
30
|
description: "Read one thingd object by collection and id.",
|
|
31
31
|
inputSchema: {
|
|
@@ -39,7 +39,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
39
39
|
openWorldHint: false,
|
|
40
40
|
},
|
|
41
41
|
}, async ({ collection, id }) => jsonResult(await db.get(collection, id)));
|
|
42
|
-
server.registerTool("
|
|
42
|
+
server.registerTool("thing_put", {
|
|
43
43
|
title: "Put Object",
|
|
44
44
|
description: "Create or replace one object-shaped memory record.",
|
|
45
45
|
inputSchema: {
|
|
@@ -70,7 +70,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
70
70
|
});
|
|
71
71
|
return jsonResult(stored);
|
|
72
72
|
});
|
|
73
|
-
server.registerTool("
|
|
73
|
+
server.registerTool("thing_delete", {
|
|
74
74
|
title: "Delete Object",
|
|
75
75
|
description: "Delete one thingd object by collection and id.",
|
|
76
76
|
inputSchema: {
|
|
@@ -97,7 +97,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
97
97
|
});
|
|
98
98
|
return jsonResult(result);
|
|
99
99
|
});
|
|
100
|
-
server.registerTool("
|
|
100
|
+
server.registerTool("thing_events_append", {
|
|
101
101
|
title: "Append Event",
|
|
102
102
|
description: "Append an event to a thingd stream.",
|
|
103
103
|
inputSchema: {
|
|
@@ -128,7 +128,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
128
128
|
});
|
|
129
129
|
return jsonResult(stored);
|
|
130
130
|
});
|
|
131
|
-
server.registerTool("
|
|
131
|
+
server.registerTool("thing_events_list", {
|
|
132
132
|
title: "List Events",
|
|
133
133
|
description: "List thingd events, optionally filtered by stream.",
|
|
134
134
|
inputSchema: {
|
|
@@ -141,7 +141,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
141
141
|
openWorldHint: false,
|
|
142
142
|
},
|
|
143
143
|
}, async ({ stream }) => jsonResult(await db.events.list(stream)));
|
|
144
|
-
server.registerTool("
|
|
144
|
+
server.registerTool("thing_queue_push", {
|
|
145
145
|
title: "Push Queue Job",
|
|
146
146
|
description: "Push a durable job onto a thingd queue.",
|
|
147
147
|
inputSchema: {
|
|
@@ -179,7 +179,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
179
179
|
});
|
|
180
180
|
return jsonResult(job);
|
|
181
181
|
});
|
|
182
|
-
server.registerTool("
|
|
182
|
+
server.registerTool("thing_queue_claim", {
|
|
183
183
|
title: "Claim Queue Job",
|
|
184
184
|
description: "Claim the next ready job from a thingd queue.",
|
|
185
185
|
inputSchema: {
|
|
@@ -213,7 +213,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
213
213
|
}
|
|
214
214
|
return jsonResult(job);
|
|
215
215
|
});
|
|
216
|
-
server.registerTool("
|
|
216
|
+
server.registerTool("thing_queue_ack", {
|
|
217
217
|
title: "Acknowledge Queue Job",
|
|
218
218
|
description: "Mark one leased queue job as completed.",
|
|
219
219
|
inputSchema: {
|
|
@@ -245,7 +245,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
245
245
|
}
|
|
246
246
|
return jsonResult(result);
|
|
247
247
|
});
|
|
248
|
-
server.registerTool("
|
|
248
|
+
server.registerTool("thing_queue_nack", {
|
|
249
249
|
title: "Reject Queue Job",
|
|
250
250
|
description: "Reject a leased queue job for retry or dead-letter routing.",
|
|
251
251
|
inputSchema: {
|
|
@@ -279,7 +279,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
279
279
|
}
|
|
280
280
|
return jsonResult(result);
|
|
281
281
|
});
|
|
282
|
-
server.registerTool("
|
|
282
|
+
server.registerTool("thing_queue_list", {
|
|
283
283
|
title: "List Queue Jobs",
|
|
284
284
|
description: "List jobs in a thingd queue.",
|
|
285
285
|
inputSchema: {
|
|
@@ -292,7 +292,7 @@ export function registerThingdTools(server, db, options = {}) {
|
|
|
292
292
|
openWorldHint: false,
|
|
293
293
|
},
|
|
294
294
|
}, async ({ queue }) => jsonResult(await db.queue(queue).list()));
|
|
295
|
-
server.registerTool("
|
|
295
|
+
server.registerTool("thing_queue_dead", {
|
|
296
296
|
title: "List Dead Queue Jobs",
|
|
297
297
|
description: "List dead-letter jobs in a thingd queue.",
|
|
298
298
|
inputSchema: {
|
package/dist/mcp-http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-http.d.ts","sourceRoot":"","sources":["../src/mcp-http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-http.d.ts","sourceRoot":"","sources":["../src/mcp-http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAM7C,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CnE"}
|
package/dist/mcp-http.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { readClusterOptionsFromEnv } from "./mcp/cluster.js";
|
|
2
2
|
import { parsePort, parseThingdDriver, readMcpAuditOptionsFromEnv } from "./mcp/config.js";
|
|
3
3
|
import { startThingdHttpServer } from "./mcp/http.js";
|
|
4
|
+
import { defaultThingdDbPath, ensureThingdDir } from "./paths.js";
|
|
4
5
|
export async function runMcpHttp(context) {
|
|
5
6
|
const parsed = context.parsed;
|
|
6
7
|
// Resolve port, host, allowUnauthenticated, etc. from flags or env
|
|
7
8
|
const portStr = parsed.flags.get("port")?.at(-1) ?? context.env.THINGD_PORT;
|
|
8
9
|
const host = parsed.flags.get("host")?.at(-1) ?? context.env.THINGD_HOST ?? "127.0.0.1";
|
|
9
|
-
const path = parsed.flags.get("path")?.at(-1) ?? context.env.THINGD_PATH ??
|
|
10
|
+
const path = parsed.flags.get("path")?.at(-1) ?? context.env.THINGD_PATH ?? defaultThingdDbPath();
|
|
10
11
|
const driverStr = parsed.flags.get("driver")?.at(-1) ?? context.env.THINGD_DRIVER;
|
|
11
12
|
const authToken = parsed.flags.get("auth-token")?.at(-1) ?? context.env.THINGD_AUTH_TOKEN;
|
|
12
13
|
const allowUnauthenticated = parsed.booleans.has("allow-unauthenticated") || parsed.flags.has("allow-unauthenticated");
|
|
13
14
|
const port = parsePort(portStr, 8757);
|
|
14
15
|
const driver = parseThingdDriver(driverStr);
|
|
16
|
+
if (path === defaultThingdDbPath()) {
|
|
17
|
+
ensureThingdDir();
|
|
18
|
+
}
|
|
15
19
|
if (!authToken) {
|
|
16
20
|
console.error("thingd-mcp HTTP runtime is starting without THINGD_AUTH_TOKEN.");
|
|
17
21
|
}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAOA,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { mkdirSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
const THINGD_DIR_NAME = ".thingd";
|
|
5
|
+
const THINGD_DB_NAME = "data.db";
|
|
6
|
+
export function defaultThingdDir() {
|
|
7
|
+
return join(homedir(), THINGD_DIR_NAME);
|
|
8
|
+
}
|
|
9
|
+
export function defaultThingdDbPath() {
|
|
10
|
+
return join(defaultThingdDir(), THINGD_DB_NAME);
|
|
11
|
+
}
|
|
12
|
+
export function ensureThingdDir() {
|
|
13
|
+
mkdirSync(defaultThingdDir(), { recursive: true });
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thingd-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Admin and operator CLI for thingd.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Sayan Mohsin",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"cli-table3": "^0.6.5",
|
|
34
34
|
"picocolors": "^1.1.1",
|
|
35
35
|
"zod": "^4.4.3",
|
|
36
|
-
"thingd": "0.
|
|
36
|
+
"thingd": "0.6.0"
|
|
37
37
|
},
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">=20"
|