huly-mcp-selfhost 3.3.0 → 3.5.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 (217) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +22 -0
  3. package/README.md +126 -17
  4. package/dist/guides/costs.md +2 -1
  5. package/dist/guides/workflow.md +3 -1
  6. package/dist/index.js +105034 -46
  7. package/dist/setup.js +4 -0
  8. package/package.json +12 -11
  9. package/dist/connection.d.ts +0 -78
  10. package/dist/connection.js +0 -271
  11. package/dist/connection.js.map +0 -1
  12. package/dist/env.d.ts +0 -1
  13. package/dist/env.js +0 -17
  14. package/dist/env.js.map +0 -1
  15. package/dist/guard.d.ts +0 -39
  16. package/dist/guard.js +0 -165
  17. package/dist/guard.js.map +0 -1
  18. package/dist/index.d.ts +0 -2
  19. package/dist/index.js.map +0 -1
  20. package/dist/junit-cli.d.ts +0 -8
  21. package/dist/junit-cli.js +0 -106
  22. package/dist/junit-cli.js.map +0 -1
  23. package/dist/registry.d.ts +0 -18
  24. package/dist/registry.js +0 -318
  25. package/dist/registry.js.map +0 -1
  26. package/dist/resources.d.ts +0 -19
  27. package/dist/resources.js +0 -255
  28. package/dist/resources.js.map +0 -1
  29. package/dist/schemas.d.ts +0 -1559
  30. package/dist/schemas.js +0 -1086
  31. package/dist/schemas.js.map +0 -1
  32. package/dist/server.d.ts +0 -29
  33. package/dist/server.js +0 -215
  34. package/dist/server.js.map +0 -1
  35. package/dist/tools/activity.d.ts +0 -10
  36. package/dist/tools/activity.js +0 -62
  37. package/dist/tools/activity.js.map +0 -1
  38. package/dist/tools/agent.d.ts +0 -156
  39. package/dist/tools/agent.js +0 -523
  40. package/dist/tools/agent.js.map +0 -1
  41. package/dist/tools/attachments.d.ts +0 -31
  42. package/dist/tools/attachments.js +0 -61
  43. package/dist/tools/attachments.js.map +0 -1
  44. package/dist/tools/calendar.d.ts +0 -49
  45. package/dist/tools/calendar.js +0 -116
  46. package/dist/tools/calendar.js.map +0 -1
  47. package/dist/tools/cards.d.ts +0 -87
  48. package/dist/tools/cards.js +0 -246
  49. package/dist/tools/cards.js.map +0 -1
  50. package/dist/tools/channels.d.ts +0 -118
  51. package/dist/tools/channels.js +0 -211
  52. package/dist/tools/channels.js.map +0 -1
  53. package/dist/tools/comments.d.ts +0 -42
  54. package/dist/tools/comments.js +0 -77
  55. package/dist/tools/comments.js.map +0 -1
  56. package/dist/tools/components.d.ts +0 -45
  57. package/dist/tools/components.js +0 -107
  58. package/dist/tools/components.js.map +0 -1
  59. package/dist/tools/contacts.d.ts +0 -69
  60. package/dist/tools/contacts.js +0 -130
  61. package/dist/tools/contacts.js.map +0 -1
  62. package/dist/tools/crm.d.ts +0 -61
  63. package/dist/tools/crm.js +0 -117
  64. package/dist/tools/crm.js.map +0 -1
  65. package/dist/tools/documents.d.ts +0 -100
  66. package/dist/tools/documents.js +0 -294
  67. package/dist/tools/documents.js.map +0 -1
  68. package/dist/tools/drive.d.ts +0 -107
  69. package/dist/tools/drive.js +0 -277
  70. package/dist/tools/drive.js.map +0 -1
  71. package/dist/tools/fields.d.ts +0 -33
  72. package/dist/tools/fields.js +0 -124
  73. package/dist/tools/fields.js.map +0 -1
  74. package/dist/tools/generic.d.ts +0 -72
  75. package/dist/tools/generic.js +0 -242
  76. package/dist/tools/generic.js.map +0 -1
  77. package/dist/tools/github.d.ts +0 -21
  78. package/dist/tools/github.js +0 -80
  79. package/dist/tools/github.js.map +0 -1
  80. package/dist/tools/hr.d.ts +0 -97
  81. package/dist/tools/hr.js +0 -150
  82. package/dist/tools/hr.js.map +0 -1
  83. package/dist/tools/inbox.d.ts +0 -23
  84. package/dist/tools/inbox.js +0 -76
  85. package/dist/tools/inbox.js.map +0 -1
  86. package/dist/tools/inventory.d.ts +0 -61
  87. package/dist/tools/inventory.js +0 -103
  88. package/dist/tools/inventory.js.map +0 -1
  89. package/dist/tools/issues.d.ts +0 -112
  90. package/dist/tools/issues.js +0 -474
  91. package/dist/tools/issues.js.map +0 -1
  92. package/dist/tools/labels.d.ts +0 -87
  93. package/dist/tools/labels.js +0 -232
  94. package/dist/tools/labels.js.map +0 -1
  95. package/dist/tools/log-time.d.ts +0 -25
  96. package/dist/tools/log-time.js +0 -95
  97. package/dist/tools/log-time.js.map +0 -1
  98. package/dist/tools/meetings.d.ts +0 -30
  99. package/dist/tools/meetings.js +0 -78
  100. package/dist/tools/meetings.js.map +0 -1
  101. package/dist/tools/members.d.ts +0 -8
  102. package/dist/tools/members.js +0 -33
  103. package/dist/tools/members.js.map +0 -1
  104. package/dist/tools/message-templates.d.ts +0 -54
  105. package/dist/tools/message-templates.js +0 -88
  106. package/dist/tools/message-templates.js.map +0 -1
  107. package/dist/tools/milestones.d.ts +0 -56
  108. package/dist/tools/milestones.js +0 -172
  109. package/dist/tools/milestones.js.map +0 -1
  110. package/dist/tools/organizations.d.ts +0 -37
  111. package/dist/tools/organizations.js +0 -88
  112. package/dist/tools/organizations.js.map +0 -1
  113. package/dist/tools/overview.d.ts +0 -55
  114. package/dist/tools/overview.js +0 -395
  115. package/dist/tools/overview.js.map +0 -1
  116. package/dist/tools/planner.d.ts +0 -60
  117. package/dist/tools/planner.js +0 -145
  118. package/dist/tools/planner.js.map +0 -1
  119. package/dist/tools/process.d.ts +0 -50
  120. package/dist/tools/process.js +0 -137
  121. package/dist/tools/process.js.map +0 -1
  122. package/dist/tools/products.d.ts +0 -17
  123. package/dist/tools/products.js +0 -45
  124. package/dist/tools/products.js.map +0 -1
  125. package/dist/tools/projects.d.ts +0 -41
  126. package/dist/tools/projects.js +0 -93
  127. package/dist/tools/projects.js.map +0 -1
  128. package/dist/tools/qms.d.ts +0 -57
  129. package/dist/tools/qms.js +0 -171
  130. package/dist/tools/qms.js.map +0 -1
  131. package/dist/tools/recruiting.d.ts +0 -112
  132. package/dist/tools/recruiting.js +0 -203
  133. package/dist/tools/recruiting.js.map +0 -1
  134. package/dist/tools/relations.d.ts +0 -72
  135. package/dist/tools/relations.js +0 -192
  136. package/dist/tools/relations.js.map +0 -1
  137. package/dist/tools/search.d.ts +0 -23
  138. package/dist/tools/search.js +0 -60
  139. package/dist/tools/search.js.map +0 -1
  140. package/dist/tools/sharing.d.ts +0 -62
  141. package/dist/tools/sharing.js +0 -149
  142. package/dist/tools/sharing.js.map +0 -1
  143. package/dist/tools/statuses.d.ts +0 -19
  144. package/dist/tools/statuses.js +0 -93
  145. package/dist/tools/statuses.js.map +0 -1
  146. package/dist/tools/surveys.d.ts +0 -22
  147. package/dist/tools/surveys.js +0 -53
  148. package/dist/tools/surveys.js.map +0 -1
  149. package/dist/tools/templates.d.ts +0 -95
  150. package/dist/tools/templates.js +0 -260
  151. package/dist/tools/templates.js.map +0 -1
  152. package/dist/tools/test-automation.d.ts +0 -81
  153. package/dist/tools/test-automation.js +0 -225
  154. package/dist/tools/test-automation.js.map +0 -1
  155. package/dist/tools/testing.d.ts +0 -234
  156. package/dist/tools/testing.js +0 -401
  157. package/dist/tools/testing.js.map +0 -1
  158. package/dist/tools/workspace-admin.d.ts +0 -55
  159. package/dist/tools/workspace-admin.js +0 -117
  160. package/dist/tools/workspace-admin.js.map +0 -1
  161. package/dist/tools/workspaces.d.ts +0 -6
  162. package/dist/tools/workspaces.js +0 -19
  163. package/dist/tools/workspaces.js.map +0 -1
  164. package/dist/utils/attributes.d.ts +0 -37
  165. package/dist/utils/attributes.js +0 -188
  166. package/dist/utils/attributes.js.map +0 -1
  167. package/dist/utils/classes.d.ts +0 -51
  168. package/dist/utils/classes.js +0 -73
  169. package/dist/utils/classes.js.map +0 -1
  170. package/dist/utils/content.d.ts +0 -11
  171. package/dist/utils/content.js +0 -86
  172. package/dist/utils/content.js.map +0 -1
  173. package/dist/utils/errors.d.ts +0 -11
  174. package/dist/utils/errors.js +0 -24
  175. package/dist/utils/errors.js.map +0 -1
  176. package/dist/utils/files.d.ts +0 -5
  177. package/dist/utils/files.js +0 -50
  178. package/dist/utils/files.js.map +0 -1
  179. package/dist/utils/format.d.ts +0 -8
  180. package/dist/utils/format.js +0 -57
  181. package/dist/utils/format.js.map +0 -1
  182. package/dist/utils/junit.d.ts +0 -13
  183. package/dist/utils/junit.js +0 -81
  184. package/dist/utils/junit.js.map +0 -1
  185. package/dist/utils/markdown.d.ts +0 -14
  186. package/dist/utils/markdown.js +0 -149
  187. package/dist/utils/markdown.js.map +0 -1
  188. package/dist/utils/meeting.d.ts +0 -13
  189. package/dist/utils/meeting.js +0 -118
  190. package/dist/utils/meeting.js.map +0 -1
  191. package/dist/utils/people.d.ts +0 -25
  192. package/dist/utils/people.js +0 -80
  193. package/dist/utils/people.js.map +0 -1
  194. package/dist/utils/redact.d.ts +0 -3
  195. package/dist/utils/redact.js +0 -26
  196. package/dist/utils/redact.js.map +0 -1
  197. package/dist/utils/resolve.d.ts +0 -17
  198. package/dist/utils/resolve.js +0 -54
  199. package/dist/utils/resolve.js.map +0 -1
  200. package/dist/utils/spec.d.ts +0 -10
  201. package/dist/utils/spec.js +0 -90
  202. package/dist/utils/spec.js.map +0 -1
  203. package/dist/utils/storage.d.ts +0 -7
  204. package/dist/utils/storage.js +0 -86
  205. package/dist/utils/storage.js.map +0 -1
  206. package/dist/utils/tasks.d.ts +0 -22
  207. package/dist/utils/tasks.js +0 -81
  208. package/dist/utils/tasks.js.map +0 -1
  209. package/dist/watch.d.ts +0 -62
  210. package/dist/watch.js +0 -405
  211. package/dist/watch.js.map +0 -1
  212. package/scripts/cleanup-issues.js +0 -141
  213. package/scripts/copy-guides.js +0 -18
  214. package/scripts/demo.js +0 -201
  215. package/scripts/import-csv.js +0 -250
  216. package/scripts/sample-tasks.csv +0 -11
  217. package/scripts/setup.js +0 -163
package/dist/setup.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ 'use strict'
3
+ process.argv.splice(2, 0, 'setup')
4
+ require('./index.js')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "huly-mcp-selfhost",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "description": "MCP server for Huly (self-hosted and Huly Cloud): 224 tools for Claude and other AI agents — issues, epics, documents, chat, planner, test management — with toolsets for low token use, an agent workflow and a Claude Code plugin.",
5
5
  "keywords": [
6
6
  "huly",
@@ -21,7 +21,7 @@
21
21
  "type": "git",
22
22
  "url": "git+https://github.com/JoKeks2023/huly-mcp.git"
23
23
  },
24
- "mcpName": "io.github.jokeks2023/huly-mcp-selfhost",
24
+ "mcpName": "io.github.JoKeks2023/huly-mcp-selfhost",
25
25
  "license": "EPL-2.0",
26
26
  "author": "Joris Conrad (https://github.com/JoKeks2023)",
27
27
  "contributors": [
@@ -30,11 +30,10 @@
30
30
  "bin": {
31
31
  "huly-mcp": "dist/index.js",
32
32
  "huly-mcp-selfhost": "dist/index.js",
33
- "huly-mcp-setup": "scripts/setup.js"
33
+ "huly-mcp-setup": "dist/setup.js"
34
34
  },
35
35
  "files": [
36
36
  "dist/",
37
- "scripts/",
38
37
  ".env.example",
39
38
  "README.md",
40
39
  "CHANGELOG.md"
@@ -43,14 +42,15 @@
43
42
  "node": ">=20"
44
43
  },
45
44
  "scripts": {
46
- "build": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\" && node --max-old-space-size=4096 node_modules/typescript/bin/tsc && node scripts/copy-guides.js",
45
+ "build": "node --max-old-space-size=4096 node_modules/typescript/bin/tsc --noEmit && node scripts/build.js",
47
46
  "dev": "tsx watch src/index.ts",
48
47
  "start": "node dist/index.js",
49
48
  "setup": "node scripts/setup.js",
50
49
  "prepublishOnly": "npm run build",
51
50
  "test": "node --import tsx --test test/*.test.ts"
52
51
  },
53
- "dependencies": {
52
+ "dependencies": {},
53
+ "devDependencies": {
54
54
  "@hcengineering/account-client": "^0.7.0",
55
55
  "@hcengineering/attachment": "0.7.0",
56
56
  "@hcengineering/chunter": "^0.7.0",
@@ -64,14 +64,15 @@
64
64
  "@hcengineering/task": "^0.7.0",
65
65
  "@hcengineering/tracker": "^0.7.0",
66
66
  "@modelcontextprotocol/sdk": "^1.32.2",
67
- "ws": "^8.22.1",
68
- "zod": "^4.6.7"
69
- },
70
- "devDependencies": {
67
+ "@types/express": "^5.0.6",
71
68
  "@types/node": "^22.0.0",
72
69
  "@types/ws": "^8.5.0",
70
+ "esbuild": "^0.28.2",
71
+ "express": "^5.3.0",
73
72
  "tsx": "^4.19.0",
74
- "typescript": "^7.0.2"
73
+ "typescript": "^7.0.2",
74
+ "ws": "^8.22.1",
75
+ "zod": "^4.6.7"
75
76
  },
76
77
  "overrides": {
77
78
  "dompurify": "^3.4.17",
@@ -1,78 +0,0 @@
1
- import { type AccountClient } from '@hcengineering/account-client';
2
- import { TxOperations, type PersonId } from '@hcengineering/core';
3
- export interface WorkspaceRef {
4
- uuid: string;
5
- /** Workspace slug, as in huly.app/<slug>. Passed to selectWorkspace(). */
6
- url: string;
7
- name: string;
8
- mode?: string;
9
- isDisabled?: boolean;
10
- }
11
- export interface WorkspaceConnection {
12
- workspace: WorkspaceRef;
13
- client: TxOperations;
14
- /** Workspace-scoped account client (token carries the workspace) — e.g. getWorkspaceMembers(). */
15
- accountClient: AccountClient;
16
- wsToken: string;
17
- workspaceUuid: string;
18
- }
19
- interface OpenConnection {
20
- client: TxOperations;
21
- close: () => Promise<void>;
22
- }
23
- export interface ConnectionManagerOptions {
24
- accountsUrl: string;
25
- email?: string;
26
- password?: string;
27
- token?: string;
28
- /** Legacy HULY_WORKSPACE: restricts this server to that single workspace. */
29
- restrictTo?: string;
30
- /** HULY_TRANSACTOR_URL: use this transactor instead of the one the account service names (e.g. an internal address). */
31
- transactorUrl?: string;
32
- createAccountClient?: (accountsUrl: string, token?: string) => AccountClient;
33
- openConnection?: (endpoint: string, token: string, socialId: PersonId) => Promise<OpenConnection>;
34
- }
35
- export declare class WorkspaceConnectionManager {
36
- private readonly opts;
37
- private readonly createAccountClient;
38
- private readonly openConnection;
39
- private session;
40
- private workspaces;
41
- private generation;
42
- private readonly connections;
43
- constructor(opts: ConnectionManagerOptions);
44
- /** All workspaces this account can use (after the optional legacy HULY_WORKSPACE restriction). */
45
- listWorkspaces(): Promise<WorkspaceRef[]>;
46
- /**
47
- * Resolve user input (slug, name or UUID; case-insensitive) to a workspace.
48
- * Without input, succeeds only if exactly one workspace is available.
49
- */
50
- resolveWorkspace(input?: string): Promise<WorkspaceRef>;
51
- /** Cached connection for the given workspace (see resolveWorkspace for the input rules). */
52
- getWorkspace(input?: string): Promise<WorkspaceConnection>;
53
- closeAll(): Promise<void>;
54
- private match;
55
- private getSession;
56
- private login;
57
- private discover;
58
- private connect;
59
- }
60
- /**
61
- * The account service answers with the public transactor address (e.g. wss://huly.example.com/_transactor).
62
- * Next to Huly — same Docker network — that detour goes out through the uplink and a tunnel and back in.
63
- * HULY_TRANSACTOR_URL replaces it, e.g. ws://huly/_transactor or ws://transactor:3333.
64
- */
65
- export declare function transactorEndpoint(endpoint: string, override: string | undefined): string;
66
- export declare function getConnectionManager(): WorkspaceConnectionManager;
67
- /** Replace the process-wide manager (tests). */
68
- export declare function setConnectionManager(next: WorkspaceConnectionManager | null): void;
69
- export declare function listWorkspaces(): Promise<WorkspaceRef[]>;
70
- export declare function getWorkspace(workspace?: string): Promise<WorkspaceConnection>;
71
- export declare function getConnection(workspace?: string): Promise<TxOperations>;
72
- export declare function getAccountClient(workspace?: string): Promise<AccountClient>;
73
- export declare function getWorkspaceInfo(workspace?: string): Promise<{
74
- wsToken: string;
75
- workspaceUuid: string;
76
- }>;
77
- export declare function closeConnection(): Promise<void>;
78
- export {};
@@ -1,271 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WorkspaceConnectionManager = void 0;
4
- exports.transactorEndpoint = transactorEndpoint;
5
- exports.getConnectionManager = getConnectionManager;
6
- exports.setConnectionManager = setConnectionManager;
7
- exports.listWorkspaces = listWorkspaces;
8
- exports.getWorkspace = getWorkspace;
9
- exports.getConnection = getConnection;
10
- exports.getAccountClient = getAccountClient;
11
- exports.getWorkspaceInfo = getWorkspaceInfo;
12
- exports.closeConnection = closeConnection;
13
- const account_client_1 = require("@hcengineering/account-client");
14
- const core_1 = require("@hcengineering/core");
15
- const server_client_1 = require("@hcengineering/server-client");
16
- async function defaultOpenConnection(endpoint, token, socialId) {
17
- const raw = await (0, server_client_1.createClient)(endpoint, token);
18
- return { client: new core_1.TxOperations(raw, socialId), close: async () => await raw.close() };
19
- }
20
- function toRef(ws) {
21
- return {
22
- uuid: String(ws.uuid),
23
- url: ws.url,
24
- name: ws.name ?? ws.url,
25
- mode: ws.mode != null ? String(ws.mode) : undefined,
26
- isDisabled: ws.isDisabled
27
- };
28
- }
29
- function describe(ws) {
30
- return ws.name !== ws.url ? `${ws.url} (${ws.name})` : ws.url;
31
- }
32
- class WorkspaceConnectionManager {
33
- opts;
34
- createAccountClient;
35
- openConnection;
36
- session = null;
37
- workspaces = null;
38
- // Bumped by closeAll() so calls that were in flight don't hand out or register connections afterwards.
39
- generation = 0;
40
- // Keyed by workspace UUID — never by user input, so "acme" and its UUID share one connection.
41
- connections = new Map();
42
- constructor(opts) {
43
- this.opts = opts;
44
- this.createAccountClient = opts.createAccountClient ?? ((url, token) => (0, account_client_1.getClient)(url, token));
45
- this.openConnection = opts.openConnection ?? defaultOpenConnection;
46
- }
47
- /** All workspaces this account can use (after the optional legacy HULY_WORKSPACE restriction). */
48
- async listWorkspaces() {
49
- if (this.workspaces === null) {
50
- const pending = this.discover();
51
- this.workspaces = pending;
52
- pending.catch(() => { if (this.workspaces === pending)
53
- this.workspaces = null; });
54
- }
55
- return await this.workspaces;
56
- }
57
- /**
58
- * Resolve user input (slug, name or UUID; case-insensitive) to a workspace.
59
- * Without input, succeeds only if exactly one workspace is available.
60
- */
61
- async resolveWorkspace(input) {
62
- let available = await this.listWorkspaces();
63
- if (input != null && input.trim() === '') {
64
- // Blank is not "omitted" — never let it fall through to a default workspace.
65
- throw new Error('Workspace must not be empty (see list_workspaces).');
66
- }
67
- if (input == null) {
68
- if (available.length === 1)
69
- return available[0];
70
- if (available.length === 0)
71
- throw new Error('No Huly workspaces are accessible with these credentials.');
72
- throw new Error(`Multiple workspaces available — pass 'workspace' explicitly (see list_workspaces). Available: ${available.map(describe).join(', ')}`);
73
- }
74
- let match = this.match(available, input);
75
- if (match === undefined) {
76
- // The account may have joined a workspace since discovery — refresh once.
77
- this.workspaces = null;
78
- available = await this.listWorkspaces();
79
- match = this.match(available, input);
80
- }
81
- if (match === undefined) {
82
- throw new Error(`Unknown workspace '${input}'. Available: ${available.map(describe).join(', ') || '(none)'}`);
83
- }
84
- return match;
85
- }
86
- /** Cached connection for the given workspace (see resolveWorkspace for the input rules). */
87
- async getWorkspace(input) {
88
- const generation = this.generation;
89
- const ws = await this.resolveWorkspace(input);
90
- if (generation !== this.generation)
91
- throw new Error('Huly connections were closed.');
92
- let pending = this.connections.get(ws.uuid);
93
- if (pending === undefined) {
94
- pending = this.connect(ws);
95
- this.connections.set(ws.uuid, pending);
96
- const current = pending;
97
- current.catch(() => { if (this.connections.get(ws.uuid) === current)
98
- this.connections.delete(ws.uuid); });
99
- }
100
- const { close, ...conn } = await pending;
101
- if (generation !== this.generation)
102
- throw new Error('Huly connections were closed.');
103
- return conn;
104
- }
105
- async closeAll() {
106
- this.generation++;
107
- const pending = [...this.connections.values()];
108
- this.connections.clear();
109
- this.workspaces = null;
110
- this.session = null;
111
- const results = await Promise.allSettled(pending);
112
- await Promise.allSettled(results.map(async (r) => { if (r.status === 'fulfilled')
113
- await r.value.close(); }));
114
- }
115
- match(available, input) {
116
- const needle = input.trim().toLowerCase();
117
- const byId = available.find((w) => w.uuid.toLowerCase() === needle || w.url.toLowerCase() === needle);
118
- if (byId !== undefined)
119
- return byId;
120
- const byName = available.filter((w) => w.name.toLowerCase() === needle);
121
- if (byName.length > 1) {
122
- throw new Error(`Workspace name '${input}' is ambiguous — use the slug or ID instead: ${byName.map((w) => `${w.url} / ${w.uuid}`).join(', ')}`);
123
- }
124
- return byName[0];
125
- }
126
- async getSession() {
127
- if (this.session === null) {
128
- const pending = this.login();
129
- this.session = pending;
130
- pending.catch(() => { if (this.session === pending)
131
- this.session = null; });
132
- }
133
- return await this.session;
134
- }
135
- async login() {
136
- const { accountsUrl, email, password, token } = this.opts;
137
- if (token != null && token !== '') {
138
- // Token auth — for SSO accounts (Google/GitHub login on huly.app).
139
- const accountClient = this.createAccountClient(accountsUrl, token);
140
- const info = await accountClient.getLoginInfoByToken();
141
- if (info == null) {
142
- throw new Error('HULY_TOKEN is invalid or expired. Please get a fresh token (npm run setup).');
143
- }
144
- if (!('socialId' in info) || info.socialId == null) {
145
- throw new Error('Token auth: no socialId returned for HULY_TOKEN.');
146
- }
147
- const session = { accountClient, socialId: info.socialId };
148
- if ('endpoint' in info && info.endpoint != null && info.token != null) {
149
- // Workspace-scoped token: its own workspace is usable directly.
150
- session.preselected = {
151
- workspace: { uuid: String(info.workspace), url: info.workspaceUrl, name: info.workspaceUrl },
152
- endpoint: info.endpoint,
153
- token: info.token
154
- };
155
- }
156
- return session;
157
- }
158
- if (email == null || email === '' || password == null || password === '') {
159
- throw new Error('Missing credentials. Provide HULY_TOKEN (for SSO accounts) or both HULY_EMAIL and HULY_PASSWORD.');
160
- }
161
- const loginInfo = await this.createAccountClient(accountsUrl).login(email, password);
162
- if (loginInfo.token == null)
163
- throw new Error('Login failed: no token returned. Check credentials.');
164
- if (loginInfo.socialId == null)
165
- throw new Error('Login failed: no socialId returned.');
166
- return { accountClient: this.createAccountClient(accountsUrl, loginInfo.token), socialId: loginInfo.socialId };
167
- }
168
- async discover() {
169
- const session = await this.getSession();
170
- let all;
171
- try {
172
- all = (await session.accountClient.getUserWorkspaces()).map(toRef);
173
- }
174
- catch (err) {
175
- // A workspace-scoped HULY_TOKEN may not be allowed to enumerate — fall back to its own workspace.
176
- if (session.preselected === undefined)
177
- throw err;
178
- all = [session.preselected.workspace];
179
- }
180
- const restrictTo = this.opts.restrictTo;
181
- if (restrictTo == null || restrictTo === '')
182
- return all;
183
- const pinned = this.match(all, restrictTo);
184
- if (pinned === undefined) {
185
- throw new Error(`HULY_WORKSPACE='${restrictTo}' is not accessible. Available: ${all.map(describe).join(', ') || '(none)'}`);
186
- }
187
- return [pinned];
188
- }
189
- async connect(ws) {
190
- const session = await this.getSession();
191
- let endpoint;
192
- let wsToken;
193
- let workspaceUuid;
194
- if (session.preselected !== undefined && session.preselected.workspace.uuid === ws.uuid) {
195
- ({ endpoint, token: wsToken } = session.preselected);
196
- workspaceUuid = ws.uuid;
197
- }
198
- else {
199
- const wsInfo = await session.accountClient.selectWorkspace(ws.url, 'external');
200
- if (wsInfo?.endpoint == null || wsInfo.token == null) {
201
- throw new Error(`Workspace '${ws.url}' not found or not accessible.`);
202
- }
203
- if (wsInfo.workspace != null && String(wsInfo.workspace) !== ws.uuid) {
204
- throw new Error(`selectWorkspace('${ws.url}') returned workspace ${String(wsInfo.workspace)}, expected ${ws.uuid}.`);
205
- }
206
- endpoint = wsInfo.endpoint;
207
- wsToken = wsInfo.token;
208
- workspaceUuid = String(wsInfo.workspace ?? ws.uuid);
209
- }
210
- endpoint = transactorEndpoint(endpoint, this.opts.transactorUrl);
211
- const { client, close } = await this.openConnection(endpoint, wsToken, session.socialId);
212
- return {
213
- workspace: ws,
214
- client,
215
- accountClient: this.createAccountClient(this.opts.accountsUrl, wsToken),
216
- wsToken,
217
- workspaceUuid,
218
- close
219
- };
220
- }
221
- }
222
- exports.WorkspaceConnectionManager = WorkspaceConnectionManager;
223
- /**
224
- * The account service answers with the public transactor address (e.g. wss://huly.example.com/_transactor).
225
- * Next to Huly — same Docker network — that detour goes out through the uplink and a tunnel and back in.
226
- * HULY_TRANSACTOR_URL replaces it, e.g. ws://huly/_transactor or ws://transactor:3333.
227
- */
228
- function transactorEndpoint(endpoint, override) {
229
- const o = override?.trim();
230
- return o != null && o !== '' ? o.replace(/\/+$/, '') : endpoint;
231
- }
232
- // ── Process-wide manager (configured from env) ──────────────────────────────
233
- let manager = null;
234
- function getConnectionManager() {
235
- if (manager === null) {
236
- manager = new WorkspaceConnectionManager({
237
- accountsUrl: process.env.HULY_ACCOUNTS_URL ?? 'https://account.huly.app',
238
- email: process.env.HULY_EMAIL,
239
- password: process.env.HULY_PASSWORD,
240
- token: process.env.HULY_TOKEN,
241
- restrictTo: process.env.HULY_WORKSPACE,
242
- transactorUrl: process.env.HULY_TRANSACTOR_URL
243
- });
244
- }
245
- return manager;
246
- }
247
- /** Replace the process-wide manager (tests). */
248
- function setConnectionManager(next) {
249
- manager = next;
250
- }
251
- async function listWorkspaces() {
252
- return await getConnectionManager().listWorkspaces();
253
- }
254
- async function getWorkspace(workspace) {
255
- return await getConnectionManager().getWorkspace(workspace);
256
- }
257
- async function getConnection(workspace) {
258
- return (await getWorkspace(workspace)).client;
259
- }
260
- async function getAccountClient(workspace) {
261
- return (await getWorkspace(workspace)).accountClient;
262
- }
263
- async function getWorkspaceInfo(workspace) {
264
- const { wsToken, workspaceUuid } = await getWorkspace(workspace);
265
- return { wsToken, workspaceUuid };
266
- }
267
- async function closeConnection() {
268
- if (manager !== null)
269
- await manager.closeAll();
270
- }
271
- //# sourceMappingURL=connection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
package/dist/env.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function normalizeEnv(env?: NodeJS.ProcessEnv): void;
package/dist/env.js DELETED
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.normalizeEnv = normalizeEnv;
4
- // Clients such as Claude Code plugins pass every configured variable, also the ones the user
5
- // left empty (or as an unresolved "${…}" placeholder). Treat those as not set, so defaults apply.
6
- function normalizeEnv(env = process.env) {
7
- for (const [key, value] of Object.entries(env)) {
8
- if (!key.startsWith('HULY_') || value == null)
9
- continue;
10
- const v = value.trim();
11
- if (v === '' || /^\$\{[^}]*\}$/.test(v))
12
- delete env[key];
13
- else if (v !== value)
14
- env[key] = v;
15
- }
16
- }
17
- //# sourceMappingURL=env.js.map
package/dist/env.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":";;;AAAA,6FAA6F;AAC7F,kGAAkG;AAClG,sBAA8B,GAAG,GAAsB,OAAO,CAAC,GAAG;IAChE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI;YAAE,SAAQ;QACvD,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;QACtB,IAAI,CAAC,KAAK,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAA;aACnD,IAAI,CAAC,KAAK,KAAK;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACpC,CAAC;AACH,CAAC"}
package/dist/guard.d.ts DELETED
@@ -1,39 +0,0 @@
1
- import type { ToolDef } from './registry';
2
- /** A tool changes data when its workspace argument is mandatory (reads may omit it). */
3
- export declare function isMutation(tool: ToolDef): boolean;
4
- /** Project keys an argument object refers to: project fields plus every "PROJ-12"-style value. */
5
- export declare function projectsIn(args: unknown, key?: string): Set<string>;
6
- export declare function parseWriteProjects(value: string | undefined): Set<string> | undefined;
7
- export declare function assertWriteAllowed(tool: ToolDef, args: unknown, allowed: Set<string> | undefined): void;
8
- export declare function audit(path: string | undefined, tool: ToolDef, args: unknown, outcome: {
9
- ok: boolean;
10
- text: string;
11
- }): void;
12
- /** Deletes and bulk/structural changes that are hard to undo. */
13
- export declare function isRisky(name: string): boolean;
14
- /**
15
- * MCP tool annotations: reads are read-only; deletes, removals and the risky tools above are
16
- * destructive; every other change (create, add, update, set, …) is marked non-destructive —
17
- * the MCP default for a write tool is "destructive", which would over-warn.
18
- * Off by default (HULY_ANNOTATIONS=1): they add ~16% to tools/list in every session.
19
- */
20
- export declare function toolAnnotations(tool: ToolDef): {
21
- title: string;
22
- readOnlyHint?: boolean;
23
- destructiveHint?: boolean;
24
- };
25
- export type ConfirmMode = 'auto' | 'off' | 'strict';
26
- export declare function parseConfirmMode(value: string | undefined): ConfirmMode;
27
- /** What the confirm callback can do with the connected client. */
28
- export interface Asker {
29
- /** True when the client can show a form (MCP elicitation). */
30
- canAsk: () => boolean;
31
- /** Shows the question; resolves true only on an explicit yes. */
32
- ask: (message: string) => Promise<boolean>;
33
- }
34
- /** One readable line per argument, without the workspace and with long values cut. */
35
- export declare function describeCall(tool: ToolDef, args: Record<string, unknown>): string;
36
- /** MCP elicitation on top of an McpServer. */
37
- export declare function elicitationAsker(server: any): Asker;
38
- /** Wraps a handler with the write scope check, the confirmation for risky tools and the audit log. */
39
- export declare function guard(tool: ToolDef, env?: NodeJS.ProcessEnv, asker?: Asker): ToolDef['handler'];