@commandable/mcp 0.2.1 → 0.4.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.
Files changed (87) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{S2P9sd4n.js → CBR-0oRi.js} +1 -1
  3. package/.output/public/_nuxt/CYsCQznM.js +59 -0
  4. package/.output/public/_nuxt/{B04gGCnx.js → Ctwv5nxD.js} +3 -3
  5. package/.output/public/_nuxt/{BvFUCPqA.js → DKO0MviJ.js} +1 -1
  6. package/.output/public/_nuxt/{d2XTSFt9.js → DOIzs5t4.js} +1 -1
  7. package/.output/public/_nuxt/KqToXREt.js +1 -0
  8. package/.output/public/_nuxt/{Dm_hd4at.js → Sdkz9rYy.js} +1 -1
  9. package/.output/public/_nuxt/_id_.DhlLK-mY.css +1 -0
  10. package/.output/public/_nuxt/builds/latest.json +1 -1
  11. package/.output/public/_nuxt/builds/meta/dd3dc5d0-c600-485d-b098-2f5b9facdf63.json +1 -0
  12. package/.output/server/chunks/build/IntegrationCredentials-styles.COcCfJmp.mjs +8 -0
  13. package/.output/server/chunks/build/IntegrationCredentials-styles.COcCfJmp.mjs.map +1 -0
  14. package/.output/server/chunks/build/{_id_-Bnxenh08.mjs → _id_-Co8jGxsD.mjs} +160 -38
  15. package/.output/server/chunks/build/{_id_-Bnxenh08.mjs.map → _id_-Co8jGxsD.mjs.map} +1 -1
  16. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  17. package/.output/server/chunks/build/{error-404-D2QibUBT.mjs → error-404-D1k2kWid.mjs} +13 -8
  18. package/.output/server/chunks/build/error-404-D1k2kWid.mjs.map +1 -0
  19. package/.output/server/chunks/build/{error-500-DYvawybF.mjs → error-500-D2K2rAfl.mjs} +13 -8
  20. package/.output/server/chunks/build/error-500-D2K2rAfl.mjs.map +1 -0
  21. package/.output/server/chunks/build/{fetch-BmYZnj75.mjs → fetch-aDh21opM.mjs} +114 -13
  22. package/.output/server/chunks/build/fetch-aDh21opM.mjs.map +1 -0
  23. package/.output/server/chunks/build/{index-CL-Gkd-Y.mjs → index-BxsJPthj.mjs} +24 -15
  24. package/.output/server/chunks/build/index-BxsJPthj.mjs.map +1 -0
  25. package/.output/server/chunks/build/{index-5H-nmhph.mjs → index-ycGPozML.mjs} +13 -8
  26. package/.output/server/chunks/build/index-ycGPozML.mjs.map +1 -0
  27. package/.output/server/chunks/build/server.mjs +17 -12
  28. package/.output/server/chunks/build/styles.mjs +2 -2
  29. package/.output/server/chunks/nitro/nitro.mjs +13082 -766
  30. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  31. package/.output/server/chunks/routes/api/_commandable/status.get.mjs +15 -8
  32. package/.output/server/chunks/routes/api/_commandable/status.get.mjs.map +1 -1
  33. package/.output/server/chunks/routes/api/catalog/_type/tools.get.mjs +13 -8
  34. package/.output/server/chunks/routes/api/catalog/_type/tools.get.mjs.map +1 -1
  35. package/.output/server/chunks/routes/api/catalog/_type/toolsets.get.mjs +13 -8
  36. package/.output/server/chunks/routes/api/catalog/_type/toolsets.get.mjs.map +1 -1
  37. package/.output/server/chunks/routes/api/catalog.get.mjs +12 -7
  38. package/.output/server/chunks/routes/api/catalog.get.mjs.map +1 -1
  39. package/.output/server/chunks/routes/api/index.get.mjs +13 -8
  40. package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
  41. package/.output/server/chunks/routes/api/index.post.mjs +12 -7
  42. package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
  43. package/.output/server/chunks/routes/api/integrations/_id/credentials-config.get.mjs +15 -12
  44. package/.output/server/chunks/routes/api/integrations/_id/credentials-config.get.mjs.map +1 -1
  45. package/.output/server/chunks/routes/api/integrations/_id/credentials-status.get.mjs +15 -12
  46. package/.output/server/chunks/routes/api/integrations/_id/credentials-status.get.mjs.map +1 -1
  47. package/.output/server/chunks/routes/api/integrations/_id/credentials.delete.mjs +18 -15
  48. package/.output/server/chunks/routes/api/integrations/_id/credentials.delete.mjs.map +1 -1
  49. package/.output/server/chunks/routes/api/integrations/_id/credentials.post.mjs +28 -24
  50. package/.output/server/chunks/routes/api/integrations/_id/credentials.post.mjs.map +1 -1
  51. package/.output/server/chunks/routes/api/integrations/_id/permissions.post.mjs +13 -8
  52. package/.output/server/chunks/routes/api/integrations/_id/permissions.post.mjs.map +1 -1
  53. package/.output/server/chunks/routes/api/integrations/_id/tools.delete.mjs +13 -8
  54. package/.output/server/chunks/routes/api/integrations/_id/tools.delete.mjs.map +1 -1
  55. package/.output/server/chunks/routes/api/integrations/_id/tools.get.mjs +27 -10
  56. package/.output/server/chunks/routes/api/integrations/_id/tools.get.mjs.map +1 -1
  57. package/.output/server/chunks/routes/api/integrations/_id/toolsets.get.mjs +13 -8
  58. package/.output/server/chunks/routes/api/integrations/_id/toolsets.get.mjs.map +1 -1
  59. package/.output/server/chunks/routes/api/integrations/_id/toolsets.post.mjs +13 -8
  60. package/.output/server/chunks/routes/api/integrations/_id/toolsets.post.mjs.map +1 -1
  61. package/.output/server/chunks/routes/api/integrations/_id_.delete.mjs +13 -8
  62. package/.output/server/chunks/routes/api/integrations/_id_.delete.mjs.map +1 -1
  63. package/.output/server/chunks/routes/health.get.mjs +12 -7
  64. package/.output/server/chunks/routes/health.get.mjs.map +1 -1
  65. package/.output/server/chunks/routes/mcp/create.mjs +13 -8
  66. package/.output/server/chunks/routes/mcp/create.mjs.map +1 -1
  67. package/.output/server/chunks/routes/mcp/static.mjs +61 -0
  68. package/.output/server/chunks/routes/mcp/static.mjs.map +1 -0
  69. package/.output/server/chunks/routes/mcp.mjs +14 -9
  70. package/.output/server/chunks/routes/mcp.mjs.map +1 -1
  71. package/.output/server/index.mjs +12 -7
  72. package/.output/server/index.mjs.map +1 -1
  73. package/.output/server/package.json +1 -1
  74. package/README.md +17 -1
  75. package/bin/cli.mjs +34 -17
  76. package/package.json +15 -14
  77. package/.output/public/_nuxt/B2dAlp_u.js +0 -59
  78. package/.output/public/_nuxt/Ba0BY0O0.js +0 -1
  79. package/.output/public/_nuxt/_id_.BKAjWkoP.css +0 -1
  80. package/.output/public/_nuxt/builds/meta/87720575-dfd4-475f-92c1-554fcd8b22f1.json +0 -1
  81. package/.output/server/chunks/build/IntegrationCredentials-styles.CULcCK6_.mjs +0 -8
  82. package/.output/server/chunks/build/IntegrationCredentials-styles.CULcCK6_.mjs.map +0 -1
  83. package/.output/server/chunks/build/error-404-D2QibUBT.mjs.map +0 -1
  84. package/.output/server/chunks/build/error-500-DYvawybF.mjs.map +0 -1
  85. package/.output/server/chunks/build/fetch-BmYZnj75.mjs.map +0 -1
  86. package/.output/server/chunks/build/index-5H-nmhph.mjs.map +0 -1
  87. package/.output/server/chunks/build/index-CL-Gkd-Y.mjs.map +0 -1
@@ -0,0 +1,61 @@
1
+ import { d as defineEventHandler, s as readBody, z as handleMcpHttp, A as setResponseStatus } from '../../nitro/nitro.mjs';
2
+ import 'node:crypto';
3
+ import '@modelcontextprotocol/sdk/server/index.js';
4
+ import '@modelcontextprotocol/sdk/server/streamableHttp.js';
5
+ import '@modelcontextprotocol/sdk/types.js';
6
+ import 'fastest-levenshtein';
7
+ import 'node:url';
8
+ import 'node:vm';
9
+ import 'turndown';
10
+ import 'marked';
11
+ import 'node:util';
12
+ import 'node:child_process';
13
+ import 'node:fs/promises';
14
+ import 'node:path';
15
+ import 'node:os';
16
+ import 'node:fs';
17
+ import 'drizzle-orm';
18
+ import 'node:buffer';
19
+ import 'google-auth-library';
20
+ import 'node:http';
21
+ import 'node:https';
22
+ import 'node:events';
23
+ import 'better-sqlite3';
24
+ import 'drizzle-orm/better-sqlite3';
25
+ import 'drizzle-orm/node-postgres';
26
+ import 'pg';
27
+ import 'drizzle-orm/better-sqlite3/migrator';
28
+ import 'drizzle-orm/node-postgres/migrator';
29
+ import 'drizzle-orm/sqlite-core';
30
+ import 'drizzle-orm/pg-core';
31
+ import 'node:process';
32
+ import 'js-yaml';
33
+ import 'zod';
34
+ import '@iconify/utils';
35
+ import 'consola';
36
+
37
+ const _static = defineEventHandler(async (event) => {
38
+ var _a, _b;
39
+ const method = event.node.req.method || "GET";
40
+ const body = method === "POST" ? await readBody(event) : void 0;
41
+ const result = await handleMcpHttp({
42
+ nodeReq: event.node.req,
43
+ nodeRes: event.node.res,
44
+ body,
45
+ endpoint: "static",
46
+ authApiKeyId: (_b = (_a = event.context.auth) == null ? void 0 : _a.apiKeyId) != null ? _b : null
47
+ });
48
+ if (result.kind === "handled") {
49
+ event._handled = true;
50
+ return;
51
+ }
52
+ setResponseStatus(event, result.statusCode);
53
+ return {
54
+ jsonrpc: "2.0",
55
+ error: { code: -32e3, message: result.message },
56
+ id: null
57
+ };
58
+ });
59
+
60
+ export { _static as default };
61
+ //# sourceMappingURL=static.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.mjs","sources":["../../../../../server/routes/mcp/static.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,gBAAe,kBAAA,CAAmB,OAAO,KAAA,KAAU;AAHnD,EAAA,IAAA,EAAA,EAAA,EAAA;AAIE,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,MAAA,IAAU,KAAA;AACxC,EAAA,MAAM,OAAO,MAAA,KAAW,MAAA,GAAS,MAAM,QAAA,CAAS,KAAK,CAAA,GAAI,MAAA;AAEzD,EAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc;AAAA,IACjC,OAAA,EAAS,MAAM,IAAA,CAAK,GAAA;AAAA,IACpB,OAAA,EAAS,MAAM,IAAA,CAAK,GAAA;AAAA,IACpB,IAAA;AAAA,IACA,QAAA,EAAU,QAAA;AAAA,IACV,eAAc,EAAA,GAAA,CAAA,EAAA,GAAA,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAd,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,aAApB,IAAA,GAAA,EAAA,GAAgC;AAAA,GAC/C,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,SAAS,SAAA,EAAW;AAC7B,IAAA,KAAA,CAAM,QAAA,GAAW,IAAA;AACjB,IAAA;AAAA,EACF;AAEA,EAAA,iBAAA,CAAkB,KAAA,EAAO,OAAO,UAAU,CAAA;AAC1C,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAA;AAAA,IACT,OAAO,EAAE,IAAA,EAAM,KAAA,EAAQ,OAAA,EAAS,OAAO,OAAA,EAAQ;AAAA,IAC/C,EAAA,EAAI;AAAA,GACN;AACF,CAAC,CAAA;;;;"}
@@ -1,31 +1,36 @@
1
- import { d as defineEventHandler, t as readBody, z as handleMcpHttp, A as setResponseStatus } from '../nitro/nitro.mjs';
2
- import '@modelcontextprotocol/sdk/types.js';
1
+ import { d as defineEventHandler, s as readBody, z as handleMcpHttp, A as setResponseStatus } from '../nitro/nitro.mjs';
2
+ import 'node:crypto';
3
3
  import '@modelcontextprotocol/sdk/server/index.js';
4
4
  import '@modelcontextprotocol/sdk/server/streamableHttp.js';
5
- import 'node:crypto';
5
+ import '@modelcontextprotocol/sdk/types.js';
6
6
  import 'fastest-levenshtein';
7
- import 'node:fs';
8
- import 'node:path';
9
7
  import 'node:url';
10
8
  import 'node:vm';
11
9
  import 'turndown';
12
10
  import 'marked';
11
+ import 'node:util';
12
+ import 'node:child_process';
13
+ import 'node:fs/promises';
14
+ import 'node:path';
15
+ import 'node:os';
16
+ import 'node:fs';
13
17
  import 'drizzle-orm';
14
18
  import 'node:buffer';
15
19
  import 'google-auth-library';
16
20
  import 'node:http';
17
21
  import 'node:https';
18
22
  import 'node:events';
19
- import 'node:os';
20
23
  import 'better-sqlite3';
21
24
  import 'drizzle-orm/better-sqlite3';
22
25
  import 'drizzle-orm/node-postgres';
23
26
  import 'pg';
27
+ import 'drizzle-orm/better-sqlite3/migrator';
28
+ import 'drizzle-orm/node-postgres/migrator';
29
+ import 'drizzle-orm/sqlite-core';
30
+ import 'drizzle-orm/pg-core';
24
31
  import 'node:process';
25
32
  import 'js-yaml';
26
33
  import 'zod';
27
- import 'drizzle-orm/sqlite-core';
28
- import 'drizzle-orm/pg-core';
29
34
  import '@iconify/utils';
30
35
  import 'consola';
31
36
 
@@ -37,7 +42,7 @@ const mcp = defineEventHandler(async (event) => {
37
42
  nodeReq: event.node.req,
38
43
  nodeRes: event.node.res,
39
44
  body,
40
- endpoint: "static",
45
+ endpoint: "dynamic",
41
46
  authApiKeyId: (_b = (_a = event.context.auth) == null ? void 0 : _a.apiKeyId) != null ? _b : null
42
47
  });
43
48
  if (result.kind === "handled") {
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.mjs","sources":["../../../../server/routes/mcp.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,YAAe,kBAAA,CAAmB,OAAO,KAAA,KAAU;AAHnD,EAAA,IAAA,EAAA,EAAA,EAAA;AAIE,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,MAAA,IAAU,KAAA;AACxC,EAAA,MAAM,OAAO,MAAA,KAAW,MAAA,GAAS,MAAM,QAAA,CAAS,KAAK,CAAA,GAAI,MAAA;AAEzD,EAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc;AAAA,IACjC,OAAA,EAAS,MAAM,IAAA,CAAK,GAAA;AAAA,IACpB,OAAA,EAAS,MAAM,IAAA,CAAK,GAAA;AAAA,IACpB,IAAA;AAAA,IACA,QAAA,EAAU,QAAA;AAAA,IACV,eAAc,EAAA,GAAA,CAAA,EAAA,GAAA,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAd,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,aAApB,IAAA,GAAA,EAAA,GAAgC;AAAA,GAC/C,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,SAAS,SAAA,EAAW;AAC7B,IAAA,KAAA,CAAM,QAAA,GAAW,IAAA;AACjB,IAAA;AAAA,EACF;AAEA,EAAA,iBAAA,CAAkB,KAAA,EAAO,OAAO,UAAU,CAAA;AAC1C,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAA;AAAA,IACT,OAAO,EAAE,IAAA,EAAM,KAAA,EAAQ,OAAA,EAAS,OAAO,OAAA,EAAQ;AAAA,IAC/C,EAAA,EAAI;AAAA,GACN;AACF,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"mcp.mjs","sources":["../../../../server/routes/mcp.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,YAAe,kBAAA,CAAmB,OAAO,KAAA,KAAU;AAHnD,EAAA,IAAA,EAAA,EAAA,EAAA;AAIE,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,MAAA,IAAU,KAAA;AACxC,EAAA,MAAM,OAAO,MAAA,KAAW,MAAA,GAAS,MAAM,QAAA,CAAS,KAAK,CAAA,GAAI,MAAA;AAEzD,EAAA,MAAM,MAAA,GAAS,MAAM,aAAA,CAAc;AAAA,IACjC,OAAA,EAAS,MAAM,IAAA,CAAK,GAAA;AAAA,IACpB,OAAA,EAAS,MAAM,IAAA,CAAK,GAAA;AAAA,IACpB,IAAA;AAAA,IACA,QAAA,EAAU,SAAA;AAAA,IACV,eAAc,EAAA,GAAA,CAAA,EAAA,GAAA,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAd,IAAA,GAAA,MAAA,GAAA,EAAA,CAAoB,aAApB,IAAA,GAAA,EAAA,GAAgC;AAAA,GAC/C,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,SAAS,SAAA,EAAW;AAC7B,IAAA,KAAA,CAAM,QAAA,GAAW,IAAA;AACjB,IAAA;AAAA,EACF;AAEA,EAAA,iBAAA,CAAkB,KAAA,EAAO,OAAO,UAAU,CAAA;AAC1C,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAA;AAAA,IACT,OAAO,EAAE,IAAA,EAAM,KAAA,EAAQ,OAAA,EAAS,OAAO,OAAA,EAAQ;AAAA,IAC/C,EAAA,EAAI;AAAA,GACN;AACF,CAAC,CAAA;;;;"}
@@ -1,31 +1,36 @@
1
1
  import process from 'node:process';globalThis._importMeta_={url:import.meta.url,env:process.env};import 'node:http';
2
2
  import 'node:https';
3
3
  export { a7 as default } from './chunks/nitro/nitro.mjs';
4
- import '@modelcontextprotocol/sdk/types.js';
4
+ import 'node:crypto';
5
5
  import '@modelcontextprotocol/sdk/server/index.js';
6
6
  import '@modelcontextprotocol/sdk/server/streamableHttp.js';
7
- import 'node:crypto';
7
+ import '@modelcontextprotocol/sdk/types.js';
8
8
  import 'fastest-levenshtein';
9
- import 'node:fs';
10
- import 'node:path';
11
9
  import 'node:url';
12
10
  import 'node:vm';
13
11
  import 'turndown';
14
12
  import 'marked';
13
+ import 'node:util';
14
+ import 'node:child_process';
15
+ import 'node:fs/promises';
16
+ import 'node:path';
17
+ import 'node:os';
18
+ import 'node:fs';
15
19
  import 'drizzle-orm';
16
20
  import 'node:buffer';
17
21
  import 'google-auth-library';
18
22
  import 'node:events';
19
- import 'node:os';
20
23
  import 'better-sqlite3';
21
24
  import 'drizzle-orm/better-sqlite3';
22
25
  import 'drizzle-orm/node-postgres';
23
26
  import 'pg';
27
+ import 'drizzle-orm/better-sqlite3/migrator';
28
+ import 'drizzle-orm/node-postgres/migrator';
29
+ import 'drizzle-orm/sqlite-core';
30
+ import 'drizzle-orm/pg-core';
24
31
  import 'node:process';
25
32
  import 'js-yaml';
26
33
  import 'zod';
27
- import 'drizzle-orm/sqlite-core';
28
- import 'drizzle-orm/pg-core';
29
34
  import '@iconify/utils';
30
35
  import 'consola';
31
36
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commandable/mcp-prod",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "dependencies": {
package/README.md CHANGED
@@ -5,7 +5,8 @@ This workspace is the published `@commandable/mcp` package.
5
5
  It owns:
6
6
 
7
7
  - the Nuxt management UI
8
- - the `/mcp` read endpoint
8
+ - the `/mcp` dynamic endpoint
9
+ - the `/mcp/static` compatibility endpoint
9
10
  - the `/mcp/create` create endpoint
10
11
  - the local server lifecycle CLI
11
12
  - the human-facing `create` and `connect` commands
@@ -29,6 +30,14 @@ yarn install
29
30
  yarn workspace @commandable/mcp dev
30
31
  ```
31
32
 
33
+ If you are testing file-processing tools locally, install the extractor dependency on the host first:
34
+
35
+ ```bash
36
+ pip3 install -r packages/core/src/file-extractor/requirements.txt
37
+ ```
38
+
39
+ Without that dependency, the app still boots normally but file-processing-backed tools stay hidden and the status/doctor surfaces report file processing as disabled. The Docker image already includes the required runtime.
40
+
32
41
  For the full local product flow, prefer the root scripts:
33
42
 
34
43
  ```bash
@@ -46,7 +55,14 @@ npx -y @commandable/mcp create --transport http --url <create-url> --api-key <ap
46
55
  npx -y @commandable/mcp connect --transport http --url <read-url> --api-key <api-key>
47
56
  ```
48
57
 
58
+ Recommended URLs:
59
+
60
+ - dynamic: `<base-url>/mcp`
61
+ - static: `<base-url>/mcp/static`
62
+ - create: `<base-url>/mcp/create`
63
+
49
64
  ## Notes
50
65
 
51
66
  - The old embedded-bundle-in-another-package model is gone.
52
67
  - This package now publishes and runs the built Nuxt app directly.
68
+ - `/_commandable/status` includes a `fileProcessing` block so hosts can verify whether extraction-backed tools are enabled.
package/bin/cli.mjs CHANGED
@@ -1,13 +1,11 @@
1
- import crypto from 'node:crypto'
2
1
  import { spawn, spawnSync } from 'node:child_process'
2
+ import crypto from 'node:crypto'
3
3
  import { existsSync, mkdirSync, openSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
4
+ import { createRequire } from 'node:module'
4
5
  import { resolve } from 'node:path'
5
6
  import { fileURLToPath } from 'node:url'
6
- import { createRequire } from 'node:module'
7
7
  import { isCancel, note, select } from '@clack/prompts'
8
- import picocolors from 'picocolors'
9
8
  import {
10
- SqlCredentialStore,
11
9
  applyConfig,
12
10
  createApiKey,
13
11
  createDbFromEnv,
@@ -16,13 +14,20 @@ import {
16
14
  getCommandableDir,
17
15
  getOrCreateEncryptionSecret,
18
16
  loadConfig,
17
+ SqlCredentialStore,
19
18
  } from '@commandable/mcp-core'
19
+ import picocolors from 'picocolors'
20
20
 
21
21
  const require = createRequire(import.meta.url)
22
22
  const pkg = require('../package.json')
23
+
23
24
  const COMMANDABLE_VERSION = String(pkg.version || '0.0.0')
24
25
  const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)))
25
26
  const serverEntry = resolve(packageRoot, '.output', 'server', 'index.mjs')
27
+ const DIGITS_ONLY_RE = /^\d+$/
28
+ const PID_LINE_RE = /^\d+$/
29
+ const SAFE_SHELL_ARG_RE = /^[\w./:=@-]+$/
30
+ const SINGLE_QUOTE_RE = /'/g
26
31
  const CLAUDE_CODE_STDIO_ENV_KEYS = [
27
32
  'COMMANDABLE_SPACE_ID',
28
33
  'COMMANDABLE_DATA_DIR',
@@ -49,7 +54,7 @@ function getFlagValue(flag) {
49
54
 
50
55
  function getUiPort() {
51
56
  const raw = process.env.COMMANDABLE_UI_PORT
52
- return raw && /^\d+$/.test(raw) ? Number(raw) : 23432
57
+ return raw && DIGITS_ONLY_RE.test(raw) ? Number(raw) : 23432
53
58
  }
54
59
 
55
60
  function getBaseUrl() {
@@ -75,7 +80,7 @@ function readDaemonPid() {
75
80
  try {
76
81
  const raw = readFileSync(daemonPidPath(), 'utf8')
77
82
  const lines = raw.split('\n').map(line => line.trim()).filter(Boolean)
78
- const pid = lines[0] && /^\d+$/.test(lines[0]) ? Number(lines[0]) : null
83
+ const pid = lines[0] && PID_LINE_RE.test(lines[0]) ? Number(lines[0]) : null
79
84
  const version = lines[1] || null
80
85
  return pid ? { pid, version } : null
81
86
  }
@@ -100,12 +105,16 @@ function stopDaemonProcess() {
100
105
  try {
101
106
  process.kill(info.pid, 'SIGTERM')
102
107
  }
103
- catch {}
108
+ catch {
109
+ // Ignore if process already exited.
110
+ }
104
111
  }
105
112
  try {
106
113
  unlinkSync(daemonPidPath())
107
114
  }
108
- catch {}
115
+ catch {
116
+ // Ignore missing pid file.
117
+ }
109
118
  return { stopped: !!info?.pid, pid: info?.pid ?? null }
110
119
  }
111
120
 
@@ -119,7 +128,9 @@ async function fetchJsonWithTimeout(url, timeoutMs) {
119
128
  try {
120
129
  json = text ? JSON.parse(text) : null
121
130
  }
122
- catch {}
131
+ catch {
132
+ // Ignore invalid JSON payloads.
133
+ }
123
134
  return { ok: response.ok, status: response.status, json }
124
135
  }
125
136
  finally {
@@ -166,9 +177,9 @@ function getClaudeCodeEnvEntries() {
166
177
  }
167
178
 
168
179
  function quoteShellArg(value) {
169
- if (/^[A-Za-z0-9_./:=@-]+$/.test(value))
180
+ if (SAFE_SHELL_ARG_RE.test(value))
170
181
  return value
171
- return `'${value.replace(/'/g, `'\"'\"'`)}'`
182
+ return `'${value.replace(SINGLE_QUOTE_RE, `'"'"'`)}'`
172
183
  }
173
184
 
174
185
  function makeReadModeConfig() {
@@ -176,7 +187,7 @@ function makeReadModeConfig() {
176
187
  mcpServers: {
177
188
  commandable: {
178
189
  command: 'npx',
179
- args: ['-y', '@commandable/mcp-connect'],
190
+ args: ['-y', '@commandable/mcp-connect', 'static-mode'],
180
191
  },
181
192
  },
182
193
  }
@@ -265,11 +276,15 @@ async function startManagementUi({ restart }) {
265
276
  try {
266
277
  process.kill(child.pid, 'SIGTERM')
267
278
  }
268
- catch {}
279
+ catch {
280
+ // Ignore if process already exited.
281
+ }
269
282
  try {
270
283
  unlinkSync(daemonPidPath())
271
284
  }
272
- catch {}
285
+ catch {
286
+ // Ignore missing pid file.
287
+ }
273
288
  console.error(`Commandable management UI failed to start at ${baseUrl}`)
274
289
  console.error(`Check the daemon log at ${logPath}`)
275
290
  process.exit(1)
@@ -308,7 +323,8 @@ async function runServe() {
308
323
  console.error(picocolors.green(`Commandable local instance ${ui.reused ? 'ready' : 'running'}.`))
309
324
  console.error(`${picocolors.dim('Base URL:')} ${baseUrl}`)
310
325
  console.error(`${picocolors.dim('Management UI:')} ${baseUrl}/`)
311
- console.error(`${picocolors.dim('MCP endpoint:')} ${baseUrl}/mcp`)
326
+ console.error(`${picocolors.dim('Dynamic MCP endpoint:')} ${baseUrl}/mcp`)
327
+ console.error(`${picocolors.dim('Static MCP endpoint:')} ${baseUrl}/mcp/static`)
312
328
  console.error(`${picocolors.dim('Create endpoint:')} ${baseUrl}/mcp/create`)
313
329
  console.error(`${picocolors.dim('Data dir:')} ${getCommandableDir()}`)
314
330
  console.error(`${picocolors.dim('SQLite:')} ${getSqlitePathForLocalState()}`)
@@ -401,6 +417,7 @@ async function runDoctor() {
401
417
  versionMatch: !!runningVersion && runningVersion === COMMANDABLE_VERSION,
402
418
  status: probe?.json ?? null,
403
419
  },
420
+ fileProcessing: probe?.json?.fileProcessing ?? null,
404
421
  }, null, 2))
405
422
  }
406
423
 
@@ -515,8 +532,8 @@ function help(exitCode = 0) {
515
532
  '',
516
533
  picocolors.bold('Notes'),
517
534
  `- ${picocolors.bold('Serve')}: starts or reuses the local Commandable instance.`,
518
- `- ${picocolors.bold('Create')}: Claude Code authoring flow. Prints or applies ${picocolors.cyan('claude mcp add')}.`,
519
- `- ${picocolors.bold('Connect')}: prints read-client connection details.`,
535
+ `- ${picocolors.bold('Create')}: Claude Code authoring flow. Prints or applies ${picocolors.cyan('claude mcp add')} for builder mode.`,
536
+ `- ${picocolors.bold('Connect')}: prints compatibility client connection details (stdio static-mode or HTTP /mcp by default).`,
520
537
  '',
521
538
  ].join('\n'))
522
539
  process.exit(exitCode)
package/package.json CHANGED
@@ -1,27 +1,33 @@
1
1
  {
2
2
  "name": "@commandable/mcp",
3
- "version": "0.2.1",
3
+ "type": "module",
4
+ "version": "0.4.0",
5
+ "packageManager": "yarn@4.12.0",
4
6
  "description": "Commandable app/server package for local management UI, HTTP endpoints, and human-facing CLI flows.",
5
7
  "license": "AGPL-3.0-only",
8
+ "homepage": "https://github.com/commandable/commandable-mcp#readme",
6
9
  "repository": {
7
10
  "type": "git",
8
11
  "url": "git+https://github.com/commandable/commandable-mcp.git",
9
12
  "directory": "app"
10
13
  },
11
- "homepage": "https://github.com/commandable/commandable-mcp#readme",
12
14
  "bugs": {
13
15
  "url": "https://github.com/commandable/commandable-mcp/issues"
14
16
  },
15
- "engines": {
16
- "node": ">=18"
17
- },
18
- "type": "module",
19
17
  "bin": {
20
18
  "commandable-mcp": "./bin/commandable-mcp.mjs"
21
19
  },
22
20
  "publishConfig": {
23
21
  "access": "public"
24
22
  },
23
+ "files": [
24
+ ".output",
25
+ "README.md",
26
+ "bin"
27
+ ],
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
25
31
  "scripts": {
26
32
  "build": "nuxt build",
27
33
  "dev": "nuxt dev",
@@ -34,7 +40,7 @@
34
40
  },
35
41
  "dependencies": {
36
42
  "@clack/prompts": "^1.0.1",
37
- "@commandable/mcp-core": "0.2.1",
43
+ "@commandable/mcp-core": "0.8.0",
38
44
  "@iconify-json/lucide": "^1.2.90",
39
45
  "@iconify-json/simple-icons": "^1.2.70",
40
46
  "@nuxt/ui": "^4.4.0",
@@ -44,15 +50,10 @@
44
50
  "tailwindcss": "^4.1.18"
45
51
  },
46
52
  "devDependencies": {
53
+ "@antfu/eslint-config": "^7.7.3",
47
54
  "@nuxt/eslint": "^1.15.1",
48
55
  "eslint": "^10.0.0",
49
56
  "typescript": "^5.9.3",
50
57
  "vue-tsc": "^3.2.4"
51
- },
52
- "files": [
53
- ".output",
54
- "bin",
55
- "README.md"
56
- ],
57
- "packageManager": "yarn@4.12.0"
58
+ }
58
59
  }