thingd-cli 0.2.0 → 0.3.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 CHANGED
@@ -77,6 +77,38 @@ You can configure the connection via environment variables or CLI flags:
77
77
  --limit <n> result limit for search and list commands
78
78
  ```
79
79
 
80
+ ### Claude Desktop & MCP Integration
81
+
82
+ The `thingd` CLI has a built-in `mcp` subcommand that exposes an MCP server over `stdio`. This allows Claude Desktop to securely connect to your `thingd` database.
83
+
84
+ **Connecting to a Local Database:**
85
+ To let Claude read and write to a local `thingd.db` file, add this to your `claude_desktop_config.json`:
86
+
87
+ ```json
88
+ {
89
+ "mcpServers": {
90
+ "thingd-local": {
91
+ "command": "thingd",
92
+ "args": ["mcp", "--path", "/absolute/path/to/thingd.db", "--driver", "native"]
93
+ }
94
+ }
95
+ }
96
+ ```
97
+
98
+ **Bridging Claude to the Cloud:**
99
+ Claude Desktop natively only supports local `stdio` servers. However, `thingd mcp` can act as a bridge! If you provide a `--url`, the CLI will launch locally but seamlessly proxy all of Claude's requests to your remote cluster:
100
+
101
+ ```json
102
+ {
103
+ "mcpServers": {
104
+ "thingd-cloud": {
105
+ "command": "thingd",
106
+ "args": ["mcp", "--url", "https://your-thingd-cloud.com/mcp", "--auth-token", "your-secret-token"]
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
80
112
  ### Command Reference
81
113
 
82
114
  **Metrics & Discovery**
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { ThingD, type ThingDDriver } from "thingd";
2
3
  type CliEnv = Record<string, string | undefined>;
3
4
  type WritableLike = {
4
5
  write(chunk: string): void;
@@ -8,6 +9,26 @@ export type RunCliOptions = {
8
9
  stdout?: WritableLike;
9
10
  stderr?: WritableLike;
10
11
  };
12
+ type ParsedArgs = {
13
+ tokens: string[];
14
+ flags: Map<string, string[]>;
15
+ booleans: Set<string>;
16
+ };
17
+ export type CliContext = {
18
+ parsed: ParsedArgs;
19
+ env: CliEnv;
20
+ stdout: WritableLike;
21
+ stderr: WritableLike;
22
+ pretty: boolean;
23
+ };
24
+ export type ConnectionOptions = {
25
+ path: string;
26
+ driver?: ThingDDriver;
27
+ authToken?: string;
28
+ cloud: boolean;
29
+ };
11
30
  export declare function runCli(args?: string[], options?: RunCliOptions): Promise<number>;
31
+ export declare function withDb(context: CliContext, callback: (db: ThingD) => Promise<void>): Promise<void>;
32
+ export declare function resolveConnection(context: CliContext): ConnectionOptions;
12
33
  export {};
13
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAiBA,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;AA4DF,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAiCjB"}
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;AAIhB,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;AAuCF,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAiCjB;AAmUD,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,CAYxE"}
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
4
4
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
5
  import { ThingD, } from "thingd";
6
6
  import { runInteractiveCli } from "./interactive.js";
7
+ import { runMcp } from "./mcp.js";
7
8
  const HELP_TEXT = `thingd
8
9
 
9
10
  Admin and operator CLI for thingd.
@@ -81,6 +82,10 @@ async function runCommand(context) {
81
82
  await runSearch(context);
82
83
  return;
83
84
  }
85
+ if (command === "mcp") {
86
+ await runMcp(context);
87
+ return;
88
+ }
84
89
  if (command === "objects") {
85
90
  await runObjects(context);
86
91
  return;
@@ -300,7 +305,7 @@ async function runQueues(context) {
300
305
  throw new Error(`Unknown queues action: ${action}`);
301
306
  });
302
307
  }
303
- async function withDb(context, callback) {
308
+ export async function withDb(context, callback) {
304
309
  const connection = resolveConnection(context);
305
310
  const db = await ThingD.open({
306
311
  path: connection.path,
@@ -336,7 +341,7 @@ function buildMemoryEvent(parsed, type) {
336
341
  ...(text === undefined ? {} : { text }),
337
342
  };
338
343
  }
339
- function resolveConnection(context) {
344
+ export function resolveConnection(context) {
340
345
  const url = stringFlag(context.parsed, "url") ?? context.env.THINGD_URL;
341
346
  const path = url ?? stringFlag(context.parsed, "path") ?? context.env.THINGD_PATH ?? ":memory:";
342
347
  const cloud = isCloudPath(path);
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { type CliContext } from "./index.js";
2
+ export declare function runMcp(context: CliContext): Promise<void>;
3
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAU,MAAM,YAAY,CAAC;AAErD,wBAAsB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAY/D"}
package/dist/mcp.js ADDED
@@ -0,0 +1,14 @@
1
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2
+ import { createThingdMcpServer } from "thingd-mcp";
3
+ import { withDb } from "./index.js";
4
+ export async function runMcp(context) {
5
+ await withDb(context, async (db) => {
6
+ // We pass empty options to createThingdMcpServer so it uses default audit behavior
7
+ const server = createThingdMcpServer(db);
8
+ const transport = new StdioServerTransport();
9
+ await server.connect(transport);
10
+ // Keep the process alive and the database connection open
11
+ // so the MCP server can continue to receive messages over stdio.
12
+ return new Promise(() => { });
13
+ });
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thingd-cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Admin and operator CLI for thingd.",
5
5
  "type": "module",
6
6
  "author": "Sayan Mohsin",
@@ -32,7 +32,8 @@
32
32
  "@modelcontextprotocol/sdk": "^1.29.0",
33
33
  "cli-table3": "^0.6.5",
34
34
  "picocolors": "^1.1.1",
35
- "thingd": "0.2.0"
35
+ "thingd": "0.3.0",
36
+ "thingd-mcp": "0.1.0"
36
37
  },
37
38
  "engines": {
38
39
  "node": ">=20"