thingd-cli 0.6.0 → 0.8.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 +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -3
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +30 -3
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +6 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/thingd-cli)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Command-line interface, Interactive TUI Dashboard, and Model Context Protocol (MCP) server for [thingd](https://www.npmjs.com/package/thingd).
|
|
6
6
|
|
|
7
|
-
This package provides the `thingd` binary
|
|
7
|
+
This package provides the unified `thingd` binary, which serves as a persistent stdio/HTTP MCP server for AI editors (Cursor, Claude Desktop), an interactive terminal UI dashboard for database operations, and a scriptable JSON utility to inspect and manage local or remote databases.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAMA,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,CA2BxE"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
2
3
|
import { pathToFileURL } from "node:url";
|
|
3
4
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
4
5
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
@@ -359,13 +360,24 @@ export function resolveConnection(context) {
|
|
|
359
360
|
const url = stringFlag(context.parsed, "url") ?? context.env.THINGD_URL;
|
|
360
361
|
const path = url ?? stringFlag(context.parsed, "path") ?? context.env.THINGD_PATH ?? defaultThingdDbPath();
|
|
361
362
|
const cloud = isCloudPath(path);
|
|
362
|
-
|
|
363
|
+
let driver = parseDriver(stringFlag(context.parsed, "driver") ?? context.env.THINGD_DRIVER);
|
|
364
|
+
if (!driver) {
|
|
365
|
+
if (cloud) {
|
|
366
|
+
driver = "cloud";
|
|
367
|
+
}
|
|
368
|
+
else if (path !== ":memory:") {
|
|
369
|
+
driver = "native";
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
driver = "memory";
|
|
373
|
+
}
|
|
374
|
+
}
|
|
363
375
|
if (!cloud && path === defaultThingdDbPath()) {
|
|
364
376
|
ensureThingdDir();
|
|
365
377
|
}
|
|
366
378
|
return {
|
|
367
379
|
path,
|
|
368
|
-
driver
|
|
380
|
+
driver,
|
|
369
381
|
authToken: stringFlag(context.parsed, "auth-token") ?? context.env.THINGD_AUTH_TOKEN,
|
|
370
382
|
cloud,
|
|
371
383
|
};
|
|
@@ -506,6 +518,15 @@ function writeJson(target, data, pretty) {
|
|
|
506
518
|
function writeText(target, text) {
|
|
507
519
|
target.write(text.endsWith("\n") ? text : `${text}\n`);
|
|
508
520
|
}
|
|
509
|
-
|
|
521
|
+
let isMain = false;
|
|
522
|
+
if (process.argv[1]) {
|
|
523
|
+
try {
|
|
524
|
+
isMain = import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href;
|
|
525
|
+
}
|
|
526
|
+
catch {
|
|
527
|
+
// Ignore realpath resolution errors.
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (isMain) {
|
|
510
531
|
process.exitCode = await runCli();
|
|
511
532
|
}
|
package/dist/install.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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,CAmDnE"}
|
package/dist/install.js
CHANGED
|
@@ -9,12 +9,23 @@ export async function runInstall(context) {
|
|
|
9
9
|
const dbPath = defaultThingdDbPath();
|
|
10
10
|
const driver = detectDriver();
|
|
11
11
|
ensureThingdDir();
|
|
12
|
-
const
|
|
12
|
+
const globalBin = findGlobalBinPath();
|
|
13
|
+
const config = globalBin
|
|
14
|
+
? {
|
|
15
|
+
command: globalBin,
|
|
16
|
+
args: ["mcp", "--path", dbPath, "--driver", driver],
|
|
17
|
+
}
|
|
18
|
+
: generateMcpConfig(nodePath, cliPath, dbPath, driver);
|
|
13
19
|
context.stderr.write(`\n${pc.bold("thingd install")}\n\n`);
|
|
14
20
|
context.stderr.write(` ${pc.green("✓")} Database path: ${pc.cyan(dbPath)}\n`);
|
|
15
21
|
context.stderr.write(` ${pc.green("✓")} Driver: ${pc.cyan(driver)}\n`);
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
if (globalBin) {
|
|
23
|
+
context.stderr.write(` ${pc.green("✓")} Command: ${pc.cyan(globalBin)}\n\n`);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
context.stderr.write(` ${pc.green("✓")} Node: ${pc.cyan(nodePath)}\n`);
|
|
27
|
+
context.stderr.write(` ${pc.green("✓")} CLI: ${pc.cyan(cliPath)}\n\n`);
|
|
28
|
+
}
|
|
18
29
|
const claudeResult = updateClaudeDesktopConfig(config);
|
|
19
30
|
if (claudeResult.updated) {
|
|
20
31
|
context.stderr.write(` ${pc.bold("Claude Desktop:")}\n`);
|
|
@@ -34,6 +45,22 @@ export async function runInstall(context) {
|
|
|
34
45
|
context.stdout.write(`${JSON.stringify(fullConfig, null, 2)}\n`);
|
|
35
46
|
context.stderr.write(`\n Restart Claude Desktop to activate. Cursor activates immediately after pasting.\n\n`);
|
|
36
47
|
}
|
|
48
|
+
function findGlobalBinPath() {
|
|
49
|
+
try {
|
|
50
|
+
const cliPath = resolveCliPath();
|
|
51
|
+
// In standard npm/nvm/pnpm global installations:
|
|
52
|
+
// CLI is at <prefix>/lib/node_modules/thingd-cli/dist/index.js
|
|
53
|
+
// Binary is at <prefix>/bin/thingd
|
|
54
|
+
const candidate = resolve(cliPath, "../../../../../bin/thingd");
|
|
55
|
+
if (existsSync(candidate)) {
|
|
56
|
+
return candidate;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Ignore
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
37
64
|
function resolveCliPath() {
|
|
38
65
|
const scriptPath = process.argv[1];
|
|
39
66
|
if (!scriptPath) {
|
package/dist/mcp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAA6B,MAAM,YAAY,CAAC;AAGxE,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB/D"}
|
package/dist/mcp.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
2
|
-
import { withDb } from "./index.js";
|
|
2
|
+
import { resolveConnection, withDb } from "./index.js";
|
|
3
3
|
import { createThingdMcpServer } from "./mcp/index.js";
|
|
4
4
|
export async function runMcp(context) {
|
|
5
|
+
const connection = resolveConnection(context);
|
|
5
6
|
await withDb(context, async (db) => {
|
|
6
7
|
// We pass empty options to createThingdMcpServer so it uses default audit behavior
|
|
7
8
|
const server = createThingdMcpServer(db);
|
|
8
9
|
const transport = new StdioServerTransport();
|
|
10
|
+
context.stderr.write(`\nthingd stdio MCP server started successfully.\n`);
|
|
11
|
+
context.stderr.write(` ✓ Database: ${connection.path}\n`);
|
|
12
|
+
context.stderr.write(` ✓ Driver: ${connection.driver ?? "memory"}\n`);
|
|
13
|
+
context.stderr.write(` ✓ Transport: Stdio (listening silently on stdin)\n\n`);
|
|
9
14
|
await server.connect(transport);
|
|
10
15
|
// Keep the process alive and the database connection open
|
|
11
16
|
// so the MCP server can continue to receive messages over stdio.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thingd-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Command-line interface, Interactive TUI Dashboard, and MCP server for thingd.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Sayan Mohsin",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -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.8.0"
|
|
37
37
|
},
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">=20"
|