@bgx4k3p/huly-mcp-server 2.0.0 → 2.0.3
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 +270 -193
- package/package.json +6 -3
- package/src/client.mjs +1869 -441
- package/src/config.mjs +25 -0
- package/src/dispatch.mjs +187 -0
- package/src/helpers.mjs +253 -0
- package/src/index.mjs +1 -0
- package/src/mcp.mjs +4 -1122
- package/src/mcpShared.mjs +601 -0
- package/src/pool.mjs +40 -29
- package/src/server.mjs +175 -976
package/README.md
CHANGED
|
@@ -3,24 +3,23 @@
|
|
|
3
3
|
[](LICENSE)
|
|
4
4
|
[](https://nodejs.org)
|
|
5
5
|
[](https://modelcontextprotocol.io)
|
|
6
|
-
[](test/integration.test.mjs)
|
|
7
|
-
[](test/integration.test.mjs)
|
|
8
|
-
[](https://www.npmjs.com/package/@bgx4k3p/huly-mcp-server)
|
|
9
6
|
[](https://huly.io)
|
|
10
7
|
[](Dockerfile)
|
|
11
8
|
|
|
12
|
-
MCP
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
MCP server providing full coverage of the [Huly](https://huly.io) SDK —
|
|
10
|
+
issues, projects, workspaces, members, and account management.
|
|
11
|
+
Two transports: **stdio** for local tools and **Streamable HTTP** for
|
|
12
|
+
remote clients. Tested against self-hosted Huly.
|
|
15
13
|
May also work with [Huly Cloud](https://app.huly.io) (not yet tested).
|
|
16
14
|
|
|
17
15
|
## Why This Exists
|
|
18
16
|
|
|
19
|
-
Huly has no
|
|
17
|
+
Huly has no public API. The only programmatic access is through their JavaScript SDK,
|
|
20
18
|
which connects via WebSocket. This server wraps that SDK and exposes **MCP tools**
|
|
21
|
-
and
|
|
19
|
+
over both stdio and **Streamable HTTP** transports — compatible with Claude Code,
|
|
20
|
+
VS Code, n8n, and any MCP client.
|
|
22
21
|
|
|
23
|
-
##
|
|
22
|
+
## Install
|
|
24
23
|
|
|
25
24
|
```bash
|
|
26
25
|
git clone https://github.com/bgx4k3p/huly-mcp-server.git
|
|
@@ -28,6 +27,14 @@ cd huly-mcp-server
|
|
|
28
27
|
npm install
|
|
29
28
|
```
|
|
30
29
|
|
|
30
|
+
> **Note:** The Huly SDK publishes packages with pnpm `workspace:`
|
|
31
|
+
> protocol in transitive dependencies, which prevents `npx` and
|
|
32
|
+
> global npm installs from working. Clone from source is required.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
31
38
|
### Authentication
|
|
32
39
|
|
|
33
40
|
You can authenticate with either **email/password** or a **token**.
|
|
@@ -57,23 +64,51 @@ export HULY_TOKEN=<paste-token-from-above>
|
|
|
57
64
|
export HULY_WORKSPACE=your-workspace
|
|
58
65
|
```
|
|
59
66
|
|
|
60
|
-
The token does not expire. You can store it in a secrets manager
|
|
61
|
-
|
|
67
|
+
The token does not expire. You can store it in a secrets manager
|
|
68
|
+
and stop exposing your password in environment variables.
|
|
62
69
|
|
|
63
70
|
---
|
|
64
71
|
|
|
65
72
|
## Integrations
|
|
66
73
|
|
|
67
|
-
### Claude Code (
|
|
74
|
+
### Claude Code (stdio)
|
|
75
|
+
|
|
76
|
+
After cloning and running `npm install`, register the server:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
claude mcp add huly \
|
|
80
|
+
-e HULY_URL=https://your-huly-instance.com \
|
|
81
|
+
-e HULY_TOKEN=your-token \
|
|
82
|
+
-e HULY_WORKSPACE=your-workspace \
|
|
83
|
+
-- node /absolute/path/to/huly-mcp-server/src/index.mjs
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Or add to your `.mcp.json` manually (token auth — recommended):
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"huly": {
|
|
92
|
+
"command": "node",
|
|
93
|
+
"args": ["/path/to/huly-mcp-server/src/index.mjs"],
|
|
94
|
+
"env": {
|
|
95
|
+
"HULY_URL": "https://your-huly-instance.com",
|
|
96
|
+
"HULY_TOKEN": "${HULY_TOKEN}",
|
|
97
|
+
"HULY_WORKSPACE": "${HULY_WORKSPACE}"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
68
103
|
|
|
69
|
-
|
|
104
|
+
Or with email/password:
|
|
70
105
|
|
|
71
106
|
```json
|
|
72
107
|
{
|
|
73
108
|
"mcpServers": {
|
|
74
109
|
"huly": {
|
|
75
110
|
"command": "node",
|
|
76
|
-
"args": ["path/to/huly-mcp-server/src/index.mjs"],
|
|
111
|
+
"args": ["/path/to/huly-mcp-server/src/index.mjs"],
|
|
77
112
|
"env": {
|
|
78
113
|
"HULY_URL": "https://your-huly-instance.com",
|
|
79
114
|
"HULY_EMAIL": "${HULY_EMAIL}",
|
|
@@ -95,53 +130,45 @@ Then ask Claude things like:
|
|
|
95
130
|
All tools have detailed descriptions optimized for AI agents.
|
|
96
131
|
MCP Resources are also available at `huly://projects/{id}` and `huly://issues/{id}`.
|
|
97
132
|
|
|
98
|
-
### n8n
|
|
133
|
+
### Streamable HTTP (n8n, VS Code, remote clients)
|
|
99
134
|
|
|
100
|
-
Start the HTTP server:
|
|
135
|
+
Start the HTTP MCP server:
|
|
101
136
|
|
|
102
137
|
```bash
|
|
103
138
|
npm run start:server
|
|
104
|
-
#
|
|
139
|
+
# MCP endpoint: http://localhost:3001/mcp
|
|
140
|
+
# Health check: http://localhost:3001/health
|
|
105
141
|
```
|
|
106
142
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
# List projects
|
|
111
|
-
curl http://localhost:3001/api/projects
|
|
143
|
+
Any MCP client that supports Streamable HTTP can connect to
|
|
144
|
+
`http://localhost:3001/mcp`. This includes n8n (v1.88+),
|
|
145
|
+
VS Code, and other MCP-compatible tools.
|
|
112
146
|
|
|
113
|
-
|
|
114
|
-
curl -X POST http://localhost:3001/api/projects/OPS/issues \
|
|
115
|
-
-H "Content-Type: application/json" \
|
|
116
|
-
-d '{"title": "New issue", "priority": "high"}'
|
|
147
|
+
To secure the endpoint, set a bearer token:
|
|
117
148
|
|
|
118
|
-
|
|
119
|
-
|
|
149
|
+
```bash
|
|
150
|
+
MCP_AUTH_TOKEN=your-secret npm run start:server
|
|
120
151
|
```
|
|
121
152
|
|
|
122
|
-
|
|
153
|
+
Clients must then include `Authorization: Bearer your-secret` in requests.
|
|
123
154
|
|
|
124
155
|
### Docker
|
|
125
156
|
|
|
126
157
|
```bash
|
|
127
158
|
docker build -t huly-mcp-server .
|
|
128
159
|
|
|
160
|
+
# Streamable HTTP server (recommended)
|
|
129
161
|
docker run -d \
|
|
130
162
|
-p 3001:3001 \
|
|
131
163
|
-e HULY_URL=https://your-huly-instance.com \
|
|
132
|
-
-e
|
|
133
|
-
-e HULY_PASSWORD=secret \
|
|
164
|
+
-e HULY_TOKEN=your-token \
|
|
134
165
|
-e HULY_WORKSPACE=my-workspace \
|
|
135
166
|
huly-mcp-server
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
For MCP stdio mode in Docker:
|
|
139
167
|
|
|
140
|
-
|
|
168
|
+
# MCP stdio mode
|
|
141
169
|
docker run -i \
|
|
142
170
|
-e HULY_URL=https://your-huly-instance.com \
|
|
143
|
-
-e
|
|
144
|
-
-e HULY_PASSWORD=secret \
|
|
171
|
+
-e HULY_TOKEN=your-token \
|
|
145
172
|
-e HULY_WORKSPACE=my-workspace \
|
|
146
173
|
huly-mcp-server node src/mcp.mjs
|
|
147
174
|
```
|
|
@@ -150,9 +177,6 @@ docker run -i \
|
|
|
150
177
|
|
|
151
178
|
## Server Configuration
|
|
152
179
|
|
|
153
|
-
These settings control the MCP server itself — authentication, rate limiting,
|
|
154
|
-
connection pooling. They are separate from the Huly credentials above.
|
|
155
|
-
|
|
156
180
|
### Environment Variables
|
|
157
181
|
|
|
158
182
|
| Variable | Required | Default | Description |
|
|
@@ -163,14 +187,16 @@ connection pooling. They are separate from the Huly credentials above.
|
|
|
163
187
|
| `HULY_EMAIL` | No | - | Huly login email (required if no token) |
|
|
164
188
|
| `HULY_PASSWORD` | No | - | Huly login password (required if no token) |
|
|
165
189
|
| `HULY_WORKSPACE` | Yes* | - | Default workspace slug |
|
|
166
|
-
|
|
|
167
|
-
| `PORT` | No | `3001` | HTTP server port |
|
|
168
|
-
| `MCP_AUTH_TOKEN` | No | - | Bearer token for HTTP server auth (disabled if unset) |
|
|
169
|
-
| `HULY_RATE_LIMIT` | No | `100` | Max requests per minute per IP |
|
|
190
|
+
| `HULY_TRANSPORT` | No | `ws` | SDK transport: `ws` (WebSocket) or `rest` (REST API) |
|
|
170
191
|
| `HULY_POOL_TTL_MS` | No | `1800000` | Connection pool TTL in ms (30 min) |
|
|
192
|
+
| **HTTP Server** | | | |
|
|
193
|
+
| `PORT` | No | `3001` | HTTP server port (auto-assigns if taken) |
|
|
194
|
+
| `MCP_AUTH_TOKEN` | No | - | Bearer token for HTTP auth (disabled if unset) |
|
|
195
|
+
| `HULY_RATE_LIMIT` | No | `200` | Max requests per minute per IP |
|
|
196
|
+
| `ALLOWED_ORIGINS` | No | `*` | CORS allowed origins (comma-separated) |
|
|
171
197
|
|
|
172
|
-
*`HULY_WORKSPACE` is required for MCP mode. For HTTP mode it can
|
|
173
|
-
omitted if every request specifies a workspace via
|
|
198
|
+
*`HULY_WORKSPACE` is required for MCP stdio mode. For HTTP mode it can
|
|
199
|
+
be omitted if every request specifies a workspace via the tool arguments.
|
|
174
200
|
|
|
175
201
|
### HTTP Server Authentication
|
|
176
202
|
|
|
@@ -183,71 +209,49 @@ openssl rand -hex 32
|
|
|
183
209
|
|
|
184
210
|
# Start with auth enabled
|
|
185
211
|
MCP_AUTH_TOKEN=your-token-here npm run start:server
|
|
186
|
-
|
|
187
|
-
# Clients must include it in requests
|
|
188
|
-
curl -H "Authorization: Bearer your-token-here" http://localhost:3001/api/projects
|
|
189
212
|
```
|
|
190
213
|
|
|
191
214
|
If `MCP_AUTH_TOKEN` is not set, auth is disabled (fine for local-only usage).
|
|
192
215
|
|
|
193
216
|
MCP stdio mode (Claude Code) does not use this token — stdio is inherently local.
|
|
194
217
|
|
|
195
|
-
### Rate Limiting
|
|
196
|
-
|
|
197
|
-
Per-IP rate limiting is always active. Response headers show current state:
|
|
198
|
-
|
|
199
|
-
```text
|
|
200
|
-
X-RateLimit-Limit: 100
|
|
201
|
-
X-RateLimit-Remaining: 97
|
|
202
|
-
X-RateLimit-Reset: 1710000000
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
Returns `429 Too Many Requests` when exceeded.
|
|
206
|
-
|
|
207
|
-
### SSE Event Stream
|
|
208
|
-
|
|
209
|
-
Subscribe to real-time mutation events:
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
curl -N http://localhost:3001/api/events
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
Events: `issue.created`, `issue.updated`, `issue.moved`, `issue.assigned`,
|
|
216
|
-
`issue.comment_added`, `issue.label_added`, `issues.batch_created`,
|
|
217
|
-
`issues.template_created`, and more.
|
|
218
|
-
|
|
219
218
|
### Multi-Workspace
|
|
220
219
|
|
|
221
|
-
All tools
|
|
220
|
+
All tools accept an optional `workspace` parameter. The connection pool
|
|
221
|
+
caches clients by workspace slug with configurable TTL:
|
|
222
222
|
|
|
223
|
-
```
|
|
224
|
-
# MCP: pass workspace in tool arguments
|
|
223
|
+
```json
|
|
225
224
|
{"tool": "list_projects", "arguments": {"workspace": "workspace-a"}}
|
|
226
|
-
|
|
227
|
-
# HTTP: via header or query param
|
|
228
|
-
curl -H "X-Huly-Workspace: workspace-a" http://localhost:3001/api/projects
|
|
229
|
-
curl "http://localhost:3001/api/projects?workspace=workspace-b"
|
|
230
225
|
```
|
|
231
226
|
|
|
227
|
+
If omitted, the `HULY_WORKSPACE` env var is used as the default.
|
|
228
|
+
|
|
232
229
|
---
|
|
233
230
|
|
|
234
231
|
## Testing
|
|
235
232
|
|
|
236
233
|
Uses Node.js built-in `node:test` and `node:assert` — no test framework dependencies.
|
|
234
|
+
Tests run twice: once with WebSocket transport, once with REST transport.
|
|
237
235
|
|
|
238
236
|
```bash
|
|
239
|
-
npm test
|
|
237
|
+
npm test # Both transports (ws + rest)
|
|
238
|
+
npm run test:ws # WebSocket only
|
|
239
|
+
npm run test:rest # REST only
|
|
240
240
|
```
|
|
241
241
|
|
|
242
|
-
|
|
242
|
+
194 tests across 101 suites:
|
|
243
|
+
|
|
244
|
+
| Suite | Tests | Description |
|
|
243
245
|
| --- | --- | --- |
|
|
244
|
-
| **Unit** | 28 | Constants, ID parsing,
|
|
245
|
-
| **Integration** |
|
|
246
|
-
| **
|
|
247
|
-
| **
|
|
248
|
-
| **
|
|
246
|
+
| **Unit** | 28 | Constants, ID parsing, rate limiting, auth logic |
|
|
247
|
+
| **Integration** | 55 | Full CRUD lifecycle against live Huly |
|
|
248
|
+
| **Dispatch** | 45 | Schema to dispatch to client param forwarding for all tools |
|
|
249
|
+
| **Account-level** | 11 | Workspaces, profile, social IDs |
|
|
250
|
+
| **Mock** | 44 | Destructive ops, token auth via mocks |
|
|
251
|
+
| **Streamable HTTP** | 11 | MCP protocol over HTTP: init, tools, resources, auth, rate limiting |
|
|
249
252
|
|
|
250
|
-
**100%
|
|
253
|
+
**100% dispatch coverage** — every tool's params are traced end-to-end
|
|
254
|
+
through the dispatch table to the client method.
|
|
251
255
|
|
|
252
256
|
---
|
|
253
257
|
|
|
@@ -274,27 +278,63 @@ bypass Application for `/_*` or these individual paths:
|
|
|
274
278
|
|
|
275
279
|
```text
|
|
276
280
|
src/
|
|
277
|
-
client.mjs # HulyClient
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
281
|
+
client.mjs # HulyClient — all business logic and SDK calls
|
|
282
|
+
helpers.mjs # Shared constants, markup conversion, JSDOM polyfills
|
|
283
|
+
dispatch.mjs # Tool-to-method dispatch table
|
|
284
|
+
pool.mjs # Connection pool — caches clients by workspace with TTL
|
|
285
|
+
mcpShared.mjs # Shared MCP server factory — tool definitions + resources
|
|
286
|
+
mcp.mjs # MCP stdio entry point (Claude Code)
|
|
287
|
+
server.mjs # MCP Streamable HTTP entry point (n8n, VS Code, remote)
|
|
288
|
+
index.mjs # CLI entry point — --get-token mode + MCP re-export
|
|
282
289
|
```
|
|
283
290
|
|
|
284
291
|
```text
|
|
285
|
-
Claude Code
|
|
286
|
-
n8n /
|
|
292
|
+
Claude Code -> stdio -> mcp.mjs -> mcpShared.mjs -> pool -> client -> Huly SDK
|
|
293
|
+
n8n / remote -> Streamable HTTP -> server.mjs -> mcpShared.mjs -> pool -> client -> Huly SDK
|
|
287
294
|
```
|
|
288
295
|
|
|
289
296
|
---
|
|
290
297
|
|
|
291
|
-
##
|
|
298
|
+
## Response Format
|
|
299
|
+
|
|
300
|
+
All read operations return **known fields** at the top level with
|
|
301
|
+
resolved, human-readable values (e.g., status names instead of IDs,
|
|
302
|
+
formatted dates). Any additional fields from the Huly SDK that aren't
|
|
303
|
+
explicitly mapped appear in an `extra` object — this future-proofs
|
|
304
|
+
the API so new SDK fields are visible without a code update.
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
{
|
|
308
|
+
"id": "PROJ-42",
|
|
309
|
+
"title": "Fix the bug",
|
|
310
|
+
"status": "In Progress",
|
|
311
|
+
"priority": "High",
|
|
312
|
+
"type": "Task",
|
|
313
|
+
"parent": "PROJ-10",
|
|
314
|
+
"childCount": 3,
|
|
315
|
+
"createdOn": 1719700000000,
|
|
316
|
+
"completedAt": null,
|
|
317
|
+
"extra": {
|
|
318
|
+
"_id": "69bab168...",
|
|
319
|
+
"_class": "tracker:class:Issue",
|
|
320
|
+
"space": "69b819b7...",
|
|
321
|
+
"kind": "tracker:taskTypes:Issue"
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Text fields (`description`, `comment`) support three input formats
|
|
327
|
+
via `descriptionFormat` / `format` parameter:
|
|
292
328
|
|
|
293
|
-
|
|
329
|
+
- **markdown** (default) — rendered as rich text in the Huly UI
|
|
330
|
+
- **html** — raw HTML, converted to rich text
|
|
331
|
+
- **plain** — stored as unformatted text
|
|
294
332
|
|
|
295
|
-
|
|
333
|
+
## API Reference
|
|
296
334
|
|
|
297
|
-
|
|
335
|
+
Full list of all MCP tools available through this server.
|
|
336
|
+
|
|
337
|
+
### Account and Workspace Management
|
|
298
338
|
|
|
299
339
|
| Tool | Description |
|
|
300
340
|
| --- | --- |
|
|
@@ -311,7 +351,7 @@ Full list of all MCP tools and HTTP endpoints available through this server.
|
|
|
311
351
|
| `change_password` | Change password |
|
|
312
352
|
| `change_username` | Change username |
|
|
313
353
|
|
|
314
|
-
|
|
354
|
+
### Invites
|
|
315
355
|
|
|
316
356
|
| Tool | Description |
|
|
317
357
|
| --- | --- |
|
|
@@ -319,7 +359,7 @@ Full list of all MCP tools and HTTP endpoints available through this server.
|
|
|
319
359
|
| `resend_invite` | Resend pending invite |
|
|
320
360
|
| `create_invite_link` | Generate shareable invite link |
|
|
321
361
|
|
|
322
|
-
|
|
362
|
+
### Integrations, Mailboxes, Social IDs, Subscriptions
|
|
323
363
|
|
|
324
364
|
| Tool | Description |
|
|
325
365
|
| --- | --- |
|
|
@@ -328,118 +368,155 @@ Full list of all MCP tools and HTTP endpoints available through this server.
|
|
|
328
368
|
| `find_person_by_social_key` / `get_social_ids` / `add_email_social_id` | Person/social ID management |
|
|
329
369
|
| `list_subscriptions` | List account subscriptions |
|
|
330
370
|
|
|
331
|
-
|
|
371
|
+
### Projects
|
|
372
|
+
|
|
373
|
+
| Tool | Description | Text Format |
|
|
374
|
+
| --- | --- | --- |
|
|
375
|
+
| `list_projects` | List all projects (supports `include_details`) | -- |
|
|
376
|
+
| `get_project` | Get project by identifier (supports `include_details`) | -- |
|
|
377
|
+
| `create_project` | Create a new project | `descriptionFormat`: md/html/plain |
|
|
378
|
+
| `update_project` | Update project name, description, privacy, default assignee | `descriptionFormat`: md/html/plain |
|
|
379
|
+
| `archive_project` | Archive or unarchive a project | -- |
|
|
380
|
+
| `delete_project` | Permanently delete a project | -- |
|
|
381
|
+
| `summarize_project` | Aggregated project metrics and health | -- |
|
|
382
|
+
|
|
383
|
+
### Issues
|
|
384
|
+
|
|
385
|
+
| Tool | Description | Text Format |
|
|
386
|
+
| --- | --- | --- |
|
|
387
|
+
| `list_issues` | List issues with filters (supports `include_details`) | -- |
|
|
388
|
+
| `get_issue` | Get full issue details (supports `include_details`) | -- |
|
|
389
|
+
| `create_issue` | Create a new issue | `descriptionFormat`: md/html/plain |
|
|
390
|
+
| `update_issue` | Update issue fields | `descriptionFormat`: md/html/plain |
|
|
391
|
+
| `delete_issue` | Permanently delete an issue | -- |
|
|
392
|
+
| `search_issues` | Full-text search across projects | -- |
|
|
393
|
+
| `get_my_issues` | Issues assigned to current user | -- |
|
|
394
|
+
| `batch_create_issues` | Create multiple issues at once | `descriptionFormat` per item |
|
|
395
|
+
| `move_issue` | Move issue between projects | -- |
|
|
396
|
+
| `create_issues_from_template` | Create from predefined templates | -- |
|
|
397
|
+
|
|
398
|
+
### Labels
|
|
332
399
|
|
|
333
400
|
| Tool | Description |
|
|
334
401
|
| --- | --- |
|
|
335
|
-
| `
|
|
336
|
-
| `
|
|
337
|
-
| `
|
|
338
|
-
| `
|
|
339
|
-
| `
|
|
340
|
-
| `
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
| `create_issues_from_template` | Create from feature/bug/sprint/release templates |
|
|
344
|
-
|
|
345
|
-
#### Labels, Relations, Milestones, Members, Comments, Time Tracking
|
|
402
|
+
| `list_labels` | List all labels in the workspace |
|
|
403
|
+
| `get_label` | Find a label by name |
|
|
404
|
+
| `create_label` | Create a new label with optional color |
|
|
405
|
+
| `update_label` | Update label name, color, or description |
|
|
406
|
+
| `add_label` | Add a label to an issue |
|
|
407
|
+
| `remove_label` | Remove a label from an issue |
|
|
408
|
+
|
|
409
|
+
### Relations
|
|
346
410
|
|
|
347
411
|
| Tool | Description |
|
|
348
412
|
| --- | --- |
|
|
349
|
-
| `
|
|
350
|
-
| `
|
|
351
|
-
| `
|
|
352
|
-
| `list_members` / `assign_issue` | Member management |
|
|
353
|
-
| `add_comment` / `list_comments` | Comments |
|
|
354
|
-
| `set_due_date` / `set_estimation` / `log_time` | Time tracking |
|
|
355
|
-
| `list_task_types` / `list_statuses` | Metadata |
|
|
356
|
-
|
|
357
|
-
### HTTP REST Endpoints
|
|
413
|
+
| `add_relation` | Add bidirectional "related to" link |
|
|
414
|
+
| `add_blocked_by` | Add "blocked by" dependency |
|
|
415
|
+
| `set_parent` | Set parent issue (epic/task hierarchy) |
|
|
358
416
|
|
|
359
|
-
|
|
417
|
+
### Components
|
|
360
418
|
|
|
361
|
-
|
|
|
419
|
+
| Tool | Description | Text Format |
|
|
362
420
|
| --- | --- | --- |
|
|
363
|
-
|
|
|
364
|
-
|
|
|
365
|
-
|
|
|
421
|
+
| `list_components` | List components in a project | -- |
|
|
422
|
+
| `get_component` | Find a component by name | -- |
|
|
423
|
+
| `create_component` | Create a new component | `descriptionFormat`: md/html/plain |
|
|
424
|
+
| `update_component` | Update component fields | `descriptionFormat`: md/html/plain |
|
|
425
|
+
| `delete_component` | Delete a component | -- |
|
|
366
426
|
|
|
367
|
-
|
|
427
|
+
### Milestones
|
|
368
428
|
|
|
369
|
-
|
|
|
429
|
+
| Tool | Description | Text Format |
|
|
370
430
|
| --- | --- | --- |
|
|
371
|
-
|
|
|
372
|
-
|
|
|
373
|
-
|
|
|
374
|
-
|
|
|
375
|
-
|
|
|
376
|
-
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
|
381
|
-
|
|
|
382
|
-
|
|
|
383
|
-
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
|
388
|
-
| GET | `/api/subscriptions` | List subscriptions |
|
|
389
|
-
|
|
390
|
-
#### Project & Issue Routes
|
|
391
|
-
|
|
392
|
-
| Method | Path | Description |
|
|
431
|
+
| `list_milestones` | List milestones (supports `include_details`) | -- |
|
|
432
|
+
| `get_milestone` | Get milestone details (supports `include_details`) | -- |
|
|
433
|
+
| `create_milestone` | Create a new milestone | `descriptionFormat`: md/html/plain |
|
|
434
|
+
| `update_milestone` | Update milestone fields | `descriptionFormat`: md/html/plain |
|
|
435
|
+
| `delete_milestone` | Delete a milestone | -- |
|
|
436
|
+
| `set_milestone` | Set or clear milestone on an issue | -- |
|
|
437
|
+
|
|
438
|
+
### Members
|
|
439
|
+
|
|
440
|
+
| Tool | Description |
|
|
441
|
+
| --- | --- |
|
|
442
|
+
| `list_members` | List all active workspace members |
|
|
443
|
+
| `get_member` | Find a member by name (fuzzy match) |
|
|
444
|
+
|
|
445
|
+
### Comments
|
|
446
|
+
|
|
447
|
+
| Tool | Description | Text Format |
|
|
393
448
|
| --- | --- | --- |
|
|
394
|
-
|
|
|
395
|
-
|
|
|
396
|
-
|
|
|
397
|
-
|
|
|
398
|
-
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
|
403
|
-
| GET | `/api/my-issues` | Issues assigned to current user |
|
|
404
|
-
| POST | `/api/projects/:project/batch-issues` | Batch create issues |
|
|
405
|
-
| POST | `/api/projects/:project/template` | Create from template |
|
|
406
|
-
| GET | `/api/search?query=...&project=...&limit=...` | Search issues |
|
|
407
|
-
|
|
408
|
-
#### Other Resource Routes
|
|
409
|
-
|
|
410
|
-
| Method | Path | Description |
|
|
449
|
+
| `list_comments` | List all comments on an issue | -- |
|
|
450
|
+
| `get_comment` | Get a specific comment by ID | -- |
|
|
451
|
+
| `add_comment` | Add a comment to an issue | `format`: md/html/plain |
|
|
452
|
+
| `update_comment` | Update comment text | `format`: md/html/plain |
|
|
453
|
+
| `delete_comment` | Delete a comment | -- |
|
|
454
|
+
|
|
455
|
+
### Time Tracking
|
|
456
|
+
|
|
457
|
+
| Tool | Description | Text Format |
|
|
411
458
|
| --- | --- | --- |
|
|
412
|
-
|
|
|
413
|
-
|
|
|
414
|
-
|
|
|
415
|
-
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
|
420
|
-
|
|
|
421
|
-
|
|
|
422
|
-
|
|
|
423
|
-
|
|
|
424
|
-
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
459
|
+
| `log_time` | Log actual time spent | `descriptionFormat`: md/html/plain |
|
|
460
|
+
| `list_time_reports` | List time reports for an issue | -- |
|
|
461
|
+
| `get_time_report` | Get a specific time report by ID | -- |
|
|
462
|
+
| `delete_time_report` | Delete a time report | -- |
|
|
463
|
+
|
|
464
|
+
### Metadata
|
|
465
|
+
|
|
466
|
+
| Tool | Description |
|
|
467
|
+
| --- | --- |
|
|
468
|
+
| `list_task_types` | List task types for a project |
|
|
469
|
+
| `get_task_type` | Find a task type by name |
|
|
470
|
+
| `list_statuses` | List issue statuses |
|
|
471
|
+
| `get_status` | Find a status by name |
|
|
472
|
+
|
|
473
|
+
> **Text format**: All text fields default to `markdown`.
|
|
474
|
+
> Set `descriptionFormat` (or `format` for comments) to
|
|
475
|
+
> `"markdown"`, `"html"`, or `"plain"`. Content is passed
|
|
476
|
+
> through unmodified -- the format tells Huly how to render it.
|
|
477
|
+
|
|
478
|
+
### include\_details Flag
|
|
479
|
+
|
|
480
|
+
Several read tools support an `include_details` boolean parameter that
|
|
481
|
+
fetches related data in a single call:
|
|
482
|
+
|
|
483
|
+
| Tool | Extra data when `include_details=true` |
|
|
484
|
+
| --- | --- |
|
|
485
|
+
| `get_issue` | Comments, time reports, relations, children |
|
|
486
|
+
| `list_issues` | Descriptions, comments, time reports, relations, children (limit reduced to 50) |
|
|
487
|
+
| `get_project` | Milestones, components, labels, members |
|
|
488
|
+
| `list_projects` | Milestones, components, labels, members per project (limit 20) |
|
|
489
|
+
| `get_milestone` | Full list of issues in the milestone |
|
|
490
|
+
| `list_milestones` | Issues list per milestone |
|
|
491
|
+
|
|
492
|
+
### CRUD Coverage
|
|
493
|
+
|
|
494
|
+
| Entity | Create | Read | List | Update | Delete |
|
|
495
|
+
| --- | --- | --- | --- | --- | --- |
|
|
496
|
+
| Project | `create_project` | `get_project` | `list_projects` | `update_project` | `delete_project` |
|
|
497
|
+
| Issue | `create_issue` | `get_issue` | `list_issues` | `update_issue` | `delete_issue` |
|
|
498
|
+
| Label | `create_label` | `get_label` | `list_labels` | `update_label` | `remove_label` |
|
|
499
|
+
| Component | `create_component` | `get_component` | `list_components` | `update_component` | `delete_component` |
|
|
500
|
+
| Milestone | `create_milestone` | `get_milestone` | `list_milestones` | `update_milestone` | `delete_milestone` |
|
|
501
|
+
| Comment | `add_comment` | `get_comment` | `list_comments` | `update_comment` | `delete_comment` |
|
|
502
|
+
| Time Report | `log_time` | `get_time_report` | `list_time_reports` | -- | `delete_time_report` |
|
|
503
|
+
| Member | -- | `get_member` | `list_members` | -- | -- |
|
|
504
|
+
| Status | -- | `get_status` | `list_statuses` | -- | -- |
|
|
505
|
+
| Task Type | -- | `get_task_type` | `list_task_types` | -- | -- |
|
|
432
506
|
|
|
433
507
|
### Issue Templates
|
|
434
508
|
|
|
435
|
-
Use `create_issues_from_template
|
|
509
|
+
Use `create_issues_from_template`:
|
|
436
510
|
|
|
437
511
|
| Template | Creates |
|
|
438
512
|
| --- | --- |
|
|
439
|
-
| `feature` |
|
|
440
|
-
| `bug` |
|
|
513
|
+
| `feature` | Parent + design/implement/test/docs/review sub-issues |
|
|
514
|
+
| `bug` | Parent + reproduce/root-cause/fix/regression-test sub-issues |
|
|
441
515
|
| `sprint` | Planning/standup/review/retro ceremony issues |
|
|
442
|
-
| `release` |
|
|
516
|
+
| `release` | Parent + freeze/QA/changelog/staging/prod/verify sub-issues |
|
|
517
|
+
|
|
518
|
+
Templates use task types like Epic/Bug when available, falling back
|
|
519
|
+
to the workspace default type otherwise.
|
|
443
520
|
|
|
444
521
|
---
|
|
445
522
|
|
|
@@ -447,7 +524,7 @@ Use `create_issues_from_template` (MCP) or `POST /api/projects/:project/template
|
|
|
447
524
|
|
|
448
525
|
`npm audit` reports moderate vulnerabilities in Svelte (SSR XSS).
|
|
449
526
|
These come from Huly SDK transitive dependencies — the SDK shares packages
|
|
450
|
-
with Huly's web frontend.
|
|
527
|
+
with Huly's web frontend. MCP server never renders HTML or uses Svelte.
|
|
451
528
|
The vulnerabilities are **not exploitable** in this context.
|
|
452
529
|
|
|
453
530
|
---
|