huly-mcp-selfhost 3.2.0 → 3.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.
- package/.env.example +10 -0
- package/CHANGELOG.md +222 -0
- package/README.md +247 -351
- package/dist/connection.d.ts +22 -0
- package/dist/connection.js +78 -5
- package/dist/connection.js.map +1 -1
- package/dist/guard.d.ts +11 -0
- package/dist/guard.js +13 -0
- package/dist/guard.js.map +1 -1
- package/dist/guides/costs.md +2 -1
- package/dist/guides/workflow.md +2 -1
- package/dist/http.d.ts +22 -0
- package/dist/http.js +213 -0
- package/dist/http.js.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/registry.js +3 -0
- package/dist/registry.js.map +1 -1
- package/dist/resources.d.ts +7 -0
- package/dist/resources.js +43 -0
- package/dist/resources.js.map +1 -1
- package/dist/schemas.d.ts +24 -0
- package/dist/schemas.js +16 -5
- package/dist/schemas.js.map +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.js +12 -4
- package/dist/server.js.map +1 -1
- package/dist/tools/diagnostics.d.ts +17 -0
- package/dist/tools/diagnostics.js +133 -0
- package/dist/tools/diagnostics.js.map +1 -0
- package/dist/tools/inbox.d.ts +16 -0
- package/dist/tools/inbox.js +64 -1
- package/dist/tools/inbox.js.map +1 -1
- package/dist/tools/issues.d.ts +2 -0
- package/dist/tools/issues.js +10 -0
- package/dist/tools/issues.js.map +1 -1
- package/package.json +17 -8
- package/scripts/copy-guides.js +18 -0
- package/scripts/setup.js +89 -33
package/README.md
CHANGED
|
@@ -1,39 +1,139 @@
|
|
|
1
1
|
# huly-mcp-selfhost
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/huly-mcp-selfhost)
|
|
4
|
+
[](https://github.com/JoKeks2023/huly-mcp/actions/workflows/ci.yml)
|
|
4
5
|
[](https://hub.docker.com/r/jokeks2023/huly-mcp)
|
|
5
|
-
[](LICENSE)
|
|
6
|
+
[](https://registry.modelcontextprotocol.io)
|
|
7
|
+
[](https://github.com/JoKeks2023/huly-mcp/blob/main/LICENSE)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Huly for AI agents.** An MCP server for [Huly](https://huly.io) — self-hosted or Huly Cloud — that lets Claude and other agents work in your workspaces: issues, epics, milestones, documents, chat, inbox, planner, test management and more. 226 tools, built for agent workflows and to spend as few tokens as possible.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
[Website](https://jokeks2023.github.io/huly-mcp/) · [Quick start](#quick-start) · [Tools](#tools-226-total-grouped-in-toolsets) · [Claude Code plugin](#claude-code-plugin) · [Changelog](https://github.com/JoKeks2023/huly-mcp/blob/main/CHANGELOG.md)
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Highlights
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
- **Everything in Huly:** tracker, documents, chat, inbox, activity, planner, calendar, GitHub PRs, contacts, drive, cards, templates, test management, recruiting, CRM, HR and more — plus read access to *any* Huly class.
|
|
16
|
+
- **Made for agents:** one-call overviews (`my_day`, `standup`, `project_report`, `get_issue_context`), `start_work` → `finish_work`, plans → epics with sub-issues, specs and meeting notes → issues, claims for parallel agents, and `huly-mcp watch` to hand issues to Claude from Huly.
|
|
17
|
+
- **Few tokens:** tools come in toolsets (default ≈11k tokens, everything ≈24k), optionally loaded on demand; pin a workspace for −10 %; compact outputs; wrong parameters are rejected with the valid list instead of silently ignored.
|
|
18
|
+
- **Safe by default:** every change names its workspace, risky tools ask first, writes can be limited to projects, optional audit log.
|
|
19
|
+
- **Claude Code plugin:** `/huly:setup` asks once per repo how Huly is used there and writes the rules; skill, hooks and `/huly:*` commands. Guides and a `setup` prompt for every other MCP client too.
|
|
20
|
+
- **Self-hosted first:** document and description content, file uploads and internal URLs work on `huly-selfhost`; one account, all its workspaces.
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
- **Self-hosted document/description writes.** Upstream's `update_document` (and, by extension, any issue description) is hardcoded against Huly Cloud's "datalake" microservice at `dl-eu.huly.app`, which `huly-selfhost` doesn't run. This fork auto-detects self-hosted deployments via `HULY_FRONT_URL` and uploads through `front`'s own `/files` contract instead — falls back to the original Cloud behavior when `HULY_FRONT_URL` is unset. See [`src/utils/storage.ts`](src/utils/storage.ts).
|
|
19
|
-
- **`description` on `create_issue`/`update_issue`.** Missing entirely upstream — issue descriptions are `MarkupBlobRef`s, same storage mechanism as document content, so this needed the same fix.
|
|
22
|
+
## Tokens, measured
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
What the model reads — measured on a real self-hosted project (≈60 issues):
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
| | Characters | ≈ Tokens |
|
|
27
|
+
|---|--:|--:|
|
|
28
|
+
| Tool list, default toolsets (98 tools, each callable directly) | 37,435 | 10.7k |
|
|
29
|
+
| Tool list, pinned workspace | 33,798 | 9.7k |
|
|
30
|
+
| Open issues of a project (one call, ≈30 issues) | 2,768 | 0.8k |
|
|
31
|
+
| One issue with description | 318 | 0.1k |
|
|
32
|
+
| Project report (done, in progress, blocked, milestones, PRs, time) | ~2,700 | 0.8k |
|
|
33
|
+
| My day (calendar, to-dos, my issues, PRs, inbox) | ~1,200 | 0.3k |
|
|
34
|
+
|
|
35
|
+
Lists default to open items, empty fields are left out, and one call answers what would otherwise take four or five. Per call and question: [`costs.md`](https://github.com/JoKeks2023/huly-mcp/blob/main/plugin/skills/huly/costs.md).
|
|
36
|
+
|
|
37
|
+
### Compared with another popular Huly MCP server
|
|
38
|
+
|
|
39
|
+
<picture>
|
|
40
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/JoKeks2023/huly-mcp/main/docs/assets/benchmark-dark.svg">
|
|
41
|
+
<img alt="Characters per answer: huly-mcp-selfhost needs 2.9× less text per answer (median), 14× smaller tool definitions, one call instead of up to four" src="https://raw.githubusercontent.com/JoKeks2023/huly-mcp/main/docs/assets/benchmark-light.svg" width="900">
|
|
42
|
+
</picture>
|
|
43
|
+
|
|
44
|
+
Same self-hosted Huly, same questions, the best parameters on both sides, measured 2026-11-11. For the other server only the text content is counted, not the duplicate JSON copy it also returns. Where we return more (components), it is because we include each component's description and code paths.
|
|
45
|
+
|
|
46
|
+
<details>
|
|
47
|
+
<summary>All numbers (characters)</summary>
|
|
48
|
+
|
|
49
|
+
| Question | huly-mcp-selfhost | Other server | Ratio |
|
|
50
|
+
|---|--:|--:|--:|
|
|
51
|
+
| Open issues of a project | 2,768 (1 call) | 11,601 (3 calls) | 4.2× less |
|
|
52
|
+
| Issues in progress | 211 (1 call) | 790 (1 call) | 3.7× less |
|
|
53
|
+
| One issue | 318 (1 call) | 585 (1 call) | 1.8× less |
|
|
54
|
+
| Everything about an issue (fields, sub-issues, comments, relations) | 1,246 (1 call) | 3,585 (4 calls) | 2.9× less |
|
|
55
|
+
| Search | 406 (1 call) | 1,405 (1 call) | 3.5× less |
|
|
56
|
+
| Projects | 550 (1 call) | 1,041 (1 call) | 1.9× less |
|
|
57
|
+
| Milestones | 208 (1 call) | 503 (1 call) | 2.4× less |
|
|
58
|
+
| Components | 1,302 (1 call) | 692 (1 call) | 2.0× more |
|
|
59
|
+
| Documents of a teamspace | 106 (1 call) | 305 (1 call) | 2.9× less |
|
|
60
|
+
| Tool definitions (49 tools with the same name) | 15,728 | 216,890 | 13.8× less |
|
|
61
|
+
|
|
62
|
+
</details>
|
|
63
|
+
|
|
64
|
+
## Quick start
|
|
65
|
+
|
|
66
|
+
You need Node.js 20+ and a Huly account — [Huly Cloud](https://huly.app) or self-hosted.
|
|
67
|
+
|
|
68
|
+
**Claude Code** — install the plugin, then fill in its settings when asked:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
/plugin marketplace add JoKeks2023/huly-mcp
|
|
72
|
+
/plugin install huly@huly-mcp
|
|
73
|
+
```
|
|
29
74
|
|
|
30
|
-
|
|
75
|
+
Then run `/huly:setup` in a repository. Details: [Claude Code plugin](#claude-code-plugin).
|
|
31
76
|
|
|
32
|
-
**
|
|
77
|
+
**Claude Desktop, Cursor, VS Code, Windsurf, Zed, …** — add the server to your client's MCP config:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"huly": {
|
|
83
|
+
"command": "npx",
|
|
84
|
+
"args": ["-y", "huly-mcp-selfhost"],
|
|
85
|
+
"env": {
|
|
86
|
+
"HULY_EMAIL": "you@example.com",
|
|
87
|
+
"HULY_PASSWORD": "your-password"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- **Self-hosted Huly:** add `"HULY_ACCOUNTS_URL": "https://huly.example.com/_accounts"` and `"HULY_FRONT_URL": "https://huly.example.com"`.
|
|
95
|
+
- **Google/GitHub login (no password):** run `npx huly-mcp-selfhost setup` and use `HULY_TOKEN` instead — see [Authentication](#authentication).
|
|
96
|
+
- **One workspace?** Add `"HULY_WORKSPACE": "<slug>"` — fewer tokens.
|
|
97
|
+
|
|
98
|
+
Config file locations and examples for each client: [Compatible clients](#compatible-clients).
|
|
99
|
+
|
|
100
|
+
**Server for a team or remote clients** — `huly-mcp-selfhost http` or the Docker image, with one Huly login per person: see [Team server over HTTP](#team-server-over-http).
|
|
101
|
+
|
|
102
|
+
Then ask: *"What's on my plate today?"*, *"Plan the login redesign as an epic in WEB"*, *"Write release notes for v1.2"*. More in [Example prompts](#example-prompts).
|
|
33
103
|
|
|
34
104
|
---
|
|
35
105
|
|
|
36
|
-
##
|
|
106
|
+
## Claude Code plugin
|
|
107
|
+
|
|
108
|
+
The repo is also a Claude Code plugin marketplace. The plugin bundles the MCP server with a workflow skill, hooks and commands:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
/plugin marketplace add JoKeks2023/huly-mcp
|
|
112
|
+
/plugin install huly@huly-mcp
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
> **Note:** the plugin starts the npm package at exactly its own version (e.g. `huly-mcp-selfhost@3.4.0`; the plugin directory does not accept version ranges), so a plugin update brings the matching server. To try a local checkout instead: `npm run build`, then point `plugin/.mcp.json` at `dist/index.js` and start `claude --plugin-dir ./plugin`.
|
|
116
|
+
|
|
117
|
+
Claude Code then asks for your Huly settings (e-mail + password or token, and for self-hosted Huly the accounts and front URL; passwords and tokens go to the OS keychain).
|
|
118
|
+
|
|
119
|
+
| Part | What it does |
|
|
120
|
+
|------|--------------|
|
|
121
|
+
| MCP server | `huly-mcp-selfhost` via `npx`, configured from the plugin settings (toolsets, on-demand loading, pinned workspace and writable projects included); tool annotations on (`HULY_ANNOTATIONS=1`) |
|
|
122
|
+
| Skill `huly` | How to use Huly while coding at the lowest token cost: the repo's `## Huly` rules first, find the project for the repo, pick up/hand back issues, status flow, duplicate check, component + milestone, epics for plans, cheapest call per question. Reference files are read only when needed: `costs.md` (measured output size per call), `onboarding.md` (bringing a project into Huly) and `features.md` (all of Huly for a software project — labels, templates, test management incl. CI import, documents, drive, custom fields, cards — with the toolsets each needs) |
|
|
123
|
+
| Hook on session start | Reports the GitHub repo and branch; a branch like `proj-12-login` points Claude to issue `PROJ-12`; points to the repo's `## Huly` rules or offers `/huly:setup` (no network, no credentials) |
|
|
124
|
+
| Hook after `gh pr create` / `gh pr merge` | Reminds Claude to link the new PR to its issue (`finish_work`) or to check the status after a merge |
|
|
125
|
+
| `/huly:setup [workspace]` | Set up Huly for this repo: asks how Huly is used here (role, where new issues go, initiative, how token-saving), writes the answers as a `## Huly` section to `CLAUDE.md`, `CLAUDE.local.md` (only you) or split between both, then optionally imports the project (status set, components, milestones, TODO/FIXME proposals, architecture document). The session-start hook offers it once while a repo has no such section |
|
|
126
|
+
| `/huly:start [PROJ-12]` | Pick up an issue (from the argument or the branch), load the context, plan |
|
|
127
|
+
| `/huly:finish [PROJ-12] [PR]` | Honest summary, PR link, status to review |
|
|
128
|
+
| `/huly:plan <goal>` | Plan → epic + sub-issues (dry run first) |
|
|
129
|
+
| `/huly:day`, `/huly:standup [since]`, `/huly:triage` | My day, stand-up, inbox triage — one call each (`my_day`, `standup`, `triage_inbox`) |
|
|
130
|
+
| `/huly:report <PROJECT> [7d]` | Project status: progress, milestones, blockers (`project_report`) |
|
|
131
|
+
|
|
132
|
+
Without the plugin, the same server works in Claude Code as a plain MCP server (see below); the MCP prompts (`setup`, `start`, `finish`, `plan`, `triage`, `standup`) and guide resources are available there too.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Tools (226 total, grouped in toolsets)
|
|
37
137
|
|
|
38
138
|
All tools except `list_workspaces` take a `workspace` argument — required for every change, optional for reads when only one workspace is available.
|
|
39
139
|
|
|
@@ -43,7 +143,7 @@ Every tool schema is sent to the model in each session (Claude Desktop loads all
|
|
|
43
143
|
|
|
44
144
|
```bash
|
|
45
145
|
HULY_TOOLSETS=all # everything
|
|
46
|
-
HULY_TOOLSETS=tracker,documents,planner # just these ('core' = list_workspaces
|
|
146
|
+
HULY_TOOLSETS=tracker,documents,planner # just these ('core' = list_workspaces and check_setup, always on)
|
|
47
147
|
```
|
|
48
148
|
|
|
49
149
|
**Load on demand** (`HULY_DYNAMIC_TOOLSETS=1`): `HULY_TOOLSETS` becomes the starting set, and Claude loads more toolsets itself via `enable_toolsets`. Called without arguments, it lists every toolset with its tools; called with names, it loads them and tells the client that the tool list changed. With `HULY_TOOLSETS=agent,inbox` a session starts at ≈1.8k tokens instead of ≈9–11k. This needs a client that reloads the tool list on `notifications/tools/list_changed`: it is tested with the MCP SDK client, but **not yet verified in Claude Desktop**. Without the variable, nothing changes.
|
|
@@ -55,7 +155,7 @@ HULY_TOOLSETS=tracker,documents,planner # just these ('core' = list_workspaces i
|
|
|
55
155
|
| `documents` | ✓ | 8 | teamspaces and documents (tree, move, rename) |
|
|
56
156
|
| `chat` | ✓ | 12 | channels, DMs, threads, edit/delete, reactions, pins |
|
|
57
157
|
| `contacts` | ✓ | 11 | members, organizations, persons, contact channels |
|
|
58
|
-
| `inbox` | ✓ |
|
|
158
|
+
| `inbox` | ✓ | 4 | notifications, triage (what changed since last read), mark read/archive; pin, hide, mark unread, follow/unfollow per object |
|
|
59
159
|
| `activity` | ✓ | 1 | change history of an issue/object |
|
|
60
160
|
| `planner` | ✓ | 5 | to-dos, time blocking |
|
|
61
161
|
| `generic` | ✓ | 4 | fulltext search across everything, read any Huly class |
|
|
@@ -82,10 +182,10 @@ HULY_TOOLSETS=tracker,documents,planner # just these ('core' = list_workspaces i
|
|
|
82
182
|
|
|
83
183
|
Context cost of `tools/list` (≈3.5 chars/token):
|
|
84
184
|
|
|
85
|
-
| | default (
|
|
185
|
+
| | default (98 tools) | `all` (226 tools) |
|
|
86
186
|
|---|--:|--:|
|
|
87
|
-
| several workspaces | ~
|
|
88
|
-
| pinned with `HULY_WORKSPACE` | ~
|
|
187
|
+
| several workspaces | ~37.4k chars ≈ **10.7k tokens** | ~82.5k chars ≈ **23.6k tokens** |
|
|
188
|
+
| pinned with `HULY_WORKSPACE` | ~33.8k chars ≈ **9.7k tokens** | ~74.1k chars ≈ **21.2k tokens** |
|
|
89
189
|
|
|
90
190
|
For comparison, 2.2.0 needed ≈12.8k tokens for 64 tools. **Using one workspace? Set `HULY_WORKSPACE`** — the `workspace` argument then disappears from every tool (−10%). **Claude Code** loads MCP tools on demand, so there even `HULY_TOOLSETS=all` costs little up front.
|
|
91
191
|
|
|
@@ -109,9 +209,9 @@ Tools, resources and prompts for AI agents working on Huly issues (toolset `agen
|
|
|
109
209
|
| `find_project_for_repo` | Workspace + project linked to a GitHub repo (`owner/name`, URL or git remote) via Huly's GitHub integration |
|
|
110
210
|
| `claim_issue` / `release_issue` | Lease an issue to an agent (label `agent:working` + comment marker) so parallel agents skip it; expires after `minutes` |
|
|
111
211
|
|
|
112
|
-
**Resources** — `huly://<workspace>/issue/<PROJ-12>` and `huly://<workspace>/document/<id>`. Your open assigned issues are listed, so in Claude Code you can `@`-mention them.
|
|
212
|
+
**Resources** — `huly://<workspace>/issue/<PROJ-12>` and `huly://<workspace>/document/<id>`. Your open assigned issues are listed, so in Claude Code you can `@`-mention them. Guides for agents in any client: `huly://guide/workflow` (how to work with Huly), `huly://guide/costs` (cheapest call per question) and `huly://guide/onboarding` (bringing a project into Huly) and `huly://guide/features` (which Huly feature to use for what, and which toolset it needs) — the same text as the plugin skill.
|
|
113
213
|
|
|
114
|
-
**Prompts** — `start`, `finish`, `plan`, `triage`, `standup` (in Claude Code: `/mcp__huly__start` …).
|
|
214
|
+
**Prompts** — `setup` (ask how Huly is used for a project and write the rules for your project instructions), `start`, `finish`, `plan`, `triage`, `standup` (in Claude Code: `/mcp__huly__start` …).
|
|
115
215
|
|
|
116
216
|
**Guard rails** (environment):
|
|
117
217
|
|
|
@@ -165,11 +265,12 @@ Options: `--run <name>`, `--parent-suite <suite>`, `--no-create` (only existing
|
|
|
165
265
|
| Category | Tool | Description |
|
|
166
266
|
|----------|------|-------------|
|
|
167
267
|
| **Workspaces** | `list_workspaces` | List the workspaces this account can access (name, slug, id) |
|
|
268
|
+
| | `check_setup` | Diagnose the setup in one call: version and whether a newer one exists, login (incl. API-token expiry), workspaces, front URL reachable, active settings — never prints secrets |
|
|
168
269
|
| **Projects** | `list_projects` | List all projects in a workspace |
|
|
169
270
|
| | `get_project` | Get project details + available statuses |
|
|
170
271
|
| | `create_project` | Create a new tracker project with a unique identifier *(tracker-admin)* |
|
|
171
272
|
| | `update_project` | Change name, description, default assignee or default status *(tracker-admin)* |
|
|
172
|
-
| **Issues** | `list_issues` | List issues — open ones by default (`status: "all"` or a status name for others), filterable by priority, milestone, component, label, assignee, parent; `offset` pages through long lists ("51–100 of 118") |
|
|
273
|
+
| **Issues** | `list_issues` | List issues — open ones by default (`status: "all"` or a status name for others), filterable by priority, milestone, component, label, assignee, parent (`null` = none for each), text in the title and due date (`overdue`, `set`, `none`); `offset` pages through long lists ("51–100 of 118") |
|
|
173
274
|
| | `get_issue` | Full details of an issue (e.g. `PROJ-42`): assignee, milestone, component, labels, parent, links |
|
|
174
275
|
| | `create_issue` | Create a new issue (with optional Markdown description) |
|
|
175
276
|
| | `update_issue` | Update title, description, status, priority, assignee, due date, component, milestone |
|
|
@@ -245,6 +346,7 @@ Options: `--run <name>`, `--parent-suite <suite>`, `--no-create` (only existing
|
|
|
245
346
|
| **Inbox** (`inbox`) | `list_notifications` | Your notifications, grouped by issue/PR/document |
|
|
246
347
|
| | `triage_inbox` | Work through the inbox in one call: per unread item its status and assignee, which fields changed and the new comments (plain text, shortened) since you last read it |
|
|
247
348
|
| | `mark_notifications_read` | Mark read by object, ids or all; optionally archive |
|
|
349
|
+
| | `manage_notifications` | For one object: `pin`/`unpin`, `hide`/`unhide`, `unread`, `unarchive`, `follow`/`unfollow` (follow = its changes reach your inbox) |
|
|
248
350
|
| **Activity** (`activity`) | `get_activity` | Who changed what, plus comments, for an issue or object |
|
|
249
351
|
| **Planner** (`planner`) | `list_todos` | Your to-dos (open/done, due date filter) |
|
|
250
352
|
| | `create_todo` | Create a to-do, optionally attached to an issue |
|
|
@@ -305,60 +407,6 @@ Options: `--run <name>`, `--parent-suite <suite>`, `--no-create` (only existing
|
|
|
305
407
|
|
|
306
408
|
---
|
|
307
409
|
|
|
308
|
-
## Requirements
|
|
309
|
-
|
|
310
|
-
- Node.js >= 20
|
|
311
|
-
- A Huly account — [huly.app](https://huly.app) (cloud) or self-hosted
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## Installing this fork
|
|
316
|
-
|
|
317
|
-
This fork is published separately as **[`huly-mcp-selfhost`](https://www.npmjs.com/package/huly-mcp-selfhost)** (`huly-mcp-sdk` is the upstream package). Three ways to run it:
|
|
318
|
-
|
|
319
|
-
### npm / npx
|
|
320
|
-
|
|
321
|
-
```json
|
|
322
|
-
"command": "npx",
|
|
323
|
-
"args": ["-y", "huly-mcp-selfhost"]
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
Every client example below uses this form.
|
|
327
|
-
|
|
328
|
-
### Clone and build
|
|
329
|
-
|
|
330
|
-
```bash
|
|
331
|
-
git clone https://github.com/JoKeks2023/huly-mcp.git
|
|
332
|
-
cd huly-mcp
|
|
333
|
-
npm install
|
|
334
|
-
npm run build
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
```json
|
|
338
|
-
"command": "node",
|
|
339
|
-
"args": ["/absolute/path/to/huly-mcp/dist/index.js"]
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
### Docker (network-reachable server, not local stdio)
|
|
343
|
-
|
|
344
|
-
For deployments where the MCP server needs to be reachable over the network (behind a reverse proxy, remote MCP clients, etc.) rather than launched locally per-client, a prebuilt image is published to Docker Hub and GHCR for every release, for `linux/amd64` and `linux/arm64`:
|
|
345
|
-
|
|
346
|
-
```bash
|
|
347
|
-
docker pull jokeks2023/huly-mcp:latest # latest release; also :3, :3.1, :3.1.0
|
|
348
|
-
# also mirrored at ghcr.io/jokeks2023/huly-mcp:latest
|
|
349
|
-
# :edge = latest build from main
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
Or with Compose — copy `.env.example` to `.env`, fill in your credentials (no workspace needed), then:
|
|
353
|
-
|
|
354
|
-
```bash
|
|
355
|
-
docker compose up -d
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
The container wraps the server with [`mcp-proxy`](https://github.com/sparfenyuk/mcp-proxy) to expose it over HTTP/SSE at `:8000/sse`, since standard MCP stdio transport can't be reached over a network directly. **Behind a reverse proxy or on a public hostname, set `MCP_ALLOWED_HOSTS`** to the host name(s) clients use, e.g. `MCP_ALLOWED_HOSTS=huly-mcp.example.com`. Otherwise mcp-proxy only accepts `localhost` and answers `421 Invalid Host header`. See [`Dockerfile`](Dockerfile) / [`docker-compose.yml`](docker-compose.yml).
|
|
359
|
-
|
|
360
|
-
---
|
|
361
|
-
|
|
362
410
|
## Workspaces (one account, several workspaces)
|
|
363
411
|
|
|
364
412
|
A single Huly account can belong to several workspaces — e.g. a personal one and a team one. This server logs in **once** with your account credentials and discovers every workspace that account can access via the account service (`getUserWorkspaces()`). You **don't configure a workspace** in the environment.
|
|
@@ -371,9 +419,9 @@ A single Huly account can belong to several workspaces — e.g. a personal one a
|
|
|
371
419
|
- **IDs are per workspace.** `PROJ-1`, a document id or a comment id identifies something only together with its workspace — the same id can exist in two workspaces. Pass the same `workspace` you got the id from.
|
|
372
420
|
- Each workspace gets its own lazily opened, cached WebSocket connection with its own workspace token (via `selectWorkspace()`), so workspaces never share state.
|
|
373
421
|
|
|
374
|
-
**Workspace slug:** the part of the Huly URL after the domain: `huly.app/workbench/`**`myteam`** → `myteam`. You don't need to look it up — `list_workspaces` (or `
|
|
422
|
+
**Workspace slug:** the part of the Huly URL after the domain: `huly.app/workbench/`**`myteam`** → `myteam`. You don't need to look it up — `list_workspaces` (or `npx huly-mcp-selfhost setup`) prints it.
|
|
375
423
|
|
|
376
|
-
**`HULY_WORKSPACE`:** pins the server to that one workspace. Tools then have no `workspace` argument at all, which saves ~
|
|
424
|
+
**`HULY_WORKSPACE`:** pins the server to that one workspace. Tools then have no `workspace` argument at all, which saves ~10% of the tool-list tokens. Leave it unset to use all workspaces of the account.
|
|
377
425
|
|
|
378
426
|
---
|
|
379
427
|
|
|
@@ -382,11 +430,12 @@ A single Huly account can belong to several workspaces — e.g. a personal one a
|
|
|
382
430
|
| Variable | Required | Purpose |
|
|
383
431
|
|----------|----------|---------|
|
|
384
432
|
| `HULY_EMAIL` + `HULY_PASSWORD` | one auth option | Account login (needs a password set on your Huly account) |
|
|
385
|
-
| `HULY_TOKEN` | one auth option | Account token for SSO accounts (Google/GitHub) — get it with `
|
|
433
|
+
| `HULY_TOKEN` | one auth option | Account token for SSO accounts (Google/GitHub) — get it with `npx huly-mcp-selfhost setup` |
|
|
386
434
|
| `HULY_ACCOUNTS_URL` | self-hosted only | Account service — login and workspace discovery. Default `https://account.huly.app`. Self-hosted: your instance's accounts URL, e.g. `https://huly.example.com/_accounts` |
|
|
387
435
|
| `HULY_FRONT_URL` | self-hosted (optional on Cloud) | Front service — document/description content and file uploads. Not involved in login or workspace discovery. Self-hosted: e.g. `https://huly.example.com` |
|
|
388
436
|
| `HULY_TRANSACTOR_URL` | no | Self-hosted, server next to Huly: connect to the transactor directly instead of the public address the account service returns, e.g. `ws://huly/_transactor` (via nginx) or `ws://transactor:3333`. Saves the detour through your uplink/tunnel. `HULY_ACCOUNTS_URL` can be internal too (`http://huly/_accounts`); an internal `HULY_FRONT_URL` also works but then invite links show the internal address |
|
|
389
437
|
| `HULY_WORKSPACE` | no | Pin the server to one workspace; tools then take no `workspace` argument (fewer tokens) |
|
|
438
|
+
| `HULY_ANNOTATIONS` | no | `1`: every tool carries MCP annotations — a title, `readOnlyHint` for reads, `destructiveHint` for deletes/removals/bulk changes. Clients can use them to allow reads without asking. Costs ~16% more tool-list tokens, so it is off by default; the Claude Code plugin turns it on |
|
|
390
439
|
| `HULY_DYNAMIC_TOOLSETS` | no | `1`: start with `HULY_TOOLSETS` and load more on demand via `enable_toolsets` (see [Toolsets](#toolsets)) |
|
|
391
440
|
| `HULY_TOOLSETS` | no | Comma-separated toolsets to enable, or `all` (see [Toolsets](#toolsets)). Default: `agent,tracker,documents,chat,contacts,inbox,activity,planner,generic` |
|
|
392
441
|
| `HULY_WRITE_PROJECTS` | no | Only allow changes in these projects, e.g. `TSK,WEB` (see [Agent workflow](#agent-workflow)) |
|
|
@@ -394,39 +443,57 @@ A single Huly account can belong to several workspaces — e.g. a personal one a
|
|
|
394
443
|
| `HULY_AGENT_NAME` | no | Default agent name for `claim_issue` (default `claude`) |
|
|
395
444
|
| `HULY_CONFIRM` | no | `auto` (default), `strict` or `off` — ask before deletes and other risky tools (see [Agent workflow](#agent-workflow)) |
|
|
396
445
|
| `HULY_FILE_ROOT` | no | Directory for local files: `upload_file` (`localPath`) and `download_file` (`savePath`) only work inside it. Off when unset — the server may run remotely |
|
|
446
|
+
| `MCP_TRANSPORT` | no | Docker only: `http` = the server's own HTTP endpoint (`/mcp`, per-user logins) instead of mcp-proxy (see [Team server over HTTP](#team-server-over-http)) |
|
|
447
|
+
| `MCP_AUTH_TOKEN` | no | HTTP mode: bearer token every client must send; required before the server's own `HULY_*` login is used over HTTP |
|
|
448
|
+
| `HULY_PREWARM` | no | `0` turns off connecting at start-up. By default the server logs in (and opens the workspace when there is only one) right after it starts, so the first tool call answers in well under a second instead of 4–12 s |
|
|
397
449
|
| `HULY_SUBSCRIBE_POLL_MS` | no | How often subscribed `huly://` resources are checked for changes (default 30000, minimum 5000) |
|
|
398
450
|
|
|
399
451
|
---
|
|
400
452
|
|
|
401
|
-
##
|
|
453
|
+
## Authentication
|
|
402
454
|
|
|
403
|
-
|
|
455
|
+
Create a `.env` file in the project root (or pass via `env` in your client config). No workspace is needed in either option.
|
|
404
456
|
|
|
457
|
+
**Option A — Email + password (recommended):**
|
|
458
|
+
|
|
459
|
+
Works if you have a password set on your Huly account (Profile → Security → Change password).
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
HULY_EMAIL=your@email.com
|
|
463
|
+
HULY_PASSWORD=yourpassword
|
|
405
464
|
```
|
|
406
|
-
|
|
407
|
-
|
|
465
|
+
|
|
466
|
+
**Option B — Token (SSO accounts: Google/GitHub):**
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
npx huly-mcp-selfhost setup # Huly Cloud
|
|
470
|
+
npx huly-mcp-selfhost setup --url https://huly.example.com # self-hosted
|
|
408
471
|
```
|
|
409
472
|
|
|
410
|
-
|
|
473
|
+
The wizard asks for your Huly address (unless `--url` or `HULY_ACCOUNTS_URL` is set), sends a one-time code to your email and lists the workspaces the account can access (a discovery test). It then prints the token and the URLs to paste into your client — for the Claude Code plugin: `/plugin` → huly → configure. In a checkout of this repo, `npm run setup` does the same and saves the token as `HULY_TOKEN` in `.env`.
|
|
411
474
|
|
|
412
|
-
|
|
475
|
+
```bash
|
|
476
|
+
HULY_TOKEN=your-token-here
|
|
477
|
+
```
|
|
413
478
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
479
|
+
A token copied from the browser (DevTools → Application → Local Storage → `token`) also works, but may be scoped to the single workspace open in that tab. If the account service refuses to list workspaces for such a token, the server falls back to that one workspace. Use `npx huly-mcp-selfhost setup` for full multi-workspace discovery.
|
|
480
|
+
|
|
481
|
+
> Tokens expire after some time. If you get an auth error, run `npx huly-mcp-selfhost setup` again or switch to email + password.
|
|
482
|
+
|
|
483
|
+
**Option C — API token (Huly → Settings → API tokens; in Huly's development branch since 2026-08, not yet in every release or self-hosted install):** bound to one workspace, with an expiry date, revocable without changing your password — the best choice for agents and CI. Use it as `HULY_TOKEN`. The server keeps it to its own workspace (even where Huly itself would allow switching), checks the expiry up front, and `check_setup` warns two weeks before it runs out. Tested against Huly's token format, not yet against a live server that issues such tokens.
|
|
484
|
+
|
|
485
|
+
**Something not working?** Ask Claude to run `check_setup`: version (and whether a newer one exists), login, workspaces, whether the front URL is reachable and which settings are active — without printing secrets.
|
|
486
|
+
|
|
487
|
+
**Self-hosted Huly:**
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
HULY_ACCOUNTS_URL=https://your-huly-instance.com/_accounts # login + workspace discovery
|
|
491
|
+
HULY_FRONT_URL=https://your-huly-instance.com # document content + file uploads
|
|
492
|
+
```
|
|
426
493
|
|
|
427
|
-
|
|
494
|
+
---
|
|
428
495
|
|
|
429
|
-
## Compatible
|
|
496
|
+
## Compatible clients
|
|
430
497
|
|
|
431
498
|
The same MCP server works across all major AI coding tools. All examples use **email + password** and the npm package via `npx`; for SSO accounts replace the two credentials with `"HULY_TOKEN": "your-token"` (see [Authentication](#authentication)). To run a local build instead, replace `npx` + args with `node` + `["/absolute/path/to/huly-mcp/dist/index.js"]`.
|
|
432
499
|
|
|
@@ -599,13 +666,71 @@ The server uses standard **stdio transport**:
|
|
|
599
666
|
- **command:** `npx` with args `["-y", "huly-mcp-selfhost"]`, or `node` with `["/absolute/path/to/huly-mcp/dist/index.js"]`
|
|
600
667
|
- **env:** `HULY_EMAIL` + `HULY_PASSWORD` (or `HULY_TOKEN`); self-hosted also `HULY_ACCOUNTS_URL` + `HULY_FRONT_URL` — see [Configuration](#configuration)
|
|
601
668
|
|
|
602
|
-
For network access (HTTP/SSE) use the [Docker image](#docker
|
|
669
|
+
For network access (HTTP/SSE) use the [Docker image](#docker).
|
|
603
670
|
|
|
604
671
|
---
|
|
605
672
|
|
|
606
673
|
<img width="932" height="401" alt="image" src="https://github.com/user-attachments/assets/0f9d9a74-ca1e-4884-bd6a-918c0fb8ddbd" />
|
|
607
674
|
|
|
608
|
-
|
|
675
|
+
---
|
|
676
|
+
|
|
677
|
+
## Running the server
|
|
678
|
+
|
|
679
|
+
### npx (recommended)
|
|
680
|
+
|
|
681
|
+
Every client example uses `"command": "npx", "args": ["-y", "huly-mcp-selfhost"]`. Pin a version (`huly-mcp-selfhost@3.4.0`) if you want updates only when you choose.
|
|
682
|
+
|
|
683
|
+
### From source
|
|
684
|
+
|
|
685
|
+
```bash
|
|
686
|
+
git clone https://github.com/JoKeks2023/huly-mcp.git
|
|
687
|
+
cd huly-mcp
|
|
688
|
+
npm ci && npm run build
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
Then use `"command": "node", "args": ["/absolute/path/to/huly-mcp/dist/index.js"]`.
|
|
692
|
+
|
|
693
|
+
### Docker
|
|
694
|
+
|
|
695
|
+
For deployments where the MCP server needs to be reachable over the network (behind a reverse proxy, remote MCP clients, etc.) rather than launched locally per-client, a prebuilt image is published to Docker Hub and GHCR for every release, for `linux/amd64` and `linux/arm64`:
|
|
696
|
+
|
|
697
|
+
```bash
|
|
698
|
+
docker pull jokeks2023/huly-mcp:latest # latest release; also :3, :3.1, :3.1.0
|
|
699
|
+
# also mirrored at ghcr.io/jokeks2023/huly-mcp:latest
|
|
700
|
+
# :edge = latest build from main
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
Or with Compose — copy `.env.example` to `.env`, fill in your credentials (no workspace needed), then:
|
|
704
|
+
|
|
705
|
+
```bash
|
|
706
|
+
docker compose up -d
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
The container wraps the server with [`mcp-proxy`](https://github.com/sparfenyuk/mcp-proxy) to expose it over HTTP/SSE at `:8000/sse`, since standard MCP stdio transport can't be reached over a network directly. **Behind a reverse proxy or on a public hostname, set `MCP_ALLOWED_HOSTS`** to the host name(s) clients use, e.g. `MCP_ALLOWED_HOSTS=huly-mcp.example.com`. Otherwise mcp-proxy only accepts `localhost` and answers `421 Invalid Host header`. See [`Dockerfile`](https://github.com/JoKeks2023/huly-mcp/blob/main/Dockerfile) / [`docker-compose.yml`](https://github.com/JoKeks2023/huly-mcp/blob/main/docker-compose.yml).
|
|
710
|
+
|
|
711
|
+
### Team server over HTTP
|
|
712
|
+
|
|
713
|
+
`huly-mcp-selfhost http` serves MCP over Streamable HTTP at `/mcp` (health check `/healthz`) — no proxy, one long-lived session per client, so logins and connections are reused (the first call of a session takes ~0.2 s). In Docker: `MCP_TRANSPORT=http`.
|
|
714
|
+
|
|
715
|
+
```bash
|
|
716
|
+
npx huly-mcp-selfhost http --host 0.0.0.0 --port 8000
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
**Everyone with their own Huly account.** A client sends its own login as headers; the session then acts as that person:
|
|
720
|
+
|
|
721
|
+
```bash
|
|
722
|
+
claude mcp add --transport http huly https://huly-mcp.example.com/mcp \
|
|
723
|
+
--header "X-Huly-Token: <your token>" # or X-Huly-Email + X-Huly-Password
|
|
724
|
+
# optional: --header "X-Huly-Workspace: acme" # pin one workspace (fewer tokens)
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
**One shared account.** The server's own `HULY_*` login is only used behind a bearer token — set `MCP_AUTH_TOKEN` and give clients `Authorization: Bearer <token>`. Without it an open port would act as that account, so the server refuses and asks for per-user headers instead. With `MCP_AUTH_TOKEN` set, every request needs the bearer token, also when it brings its own login.
|
|
728
|
+
|
|
729
|
+
Set `MCP_ALLOWED_HOSTS` to the host names clients use (DNS-rebinding protection). Use HTTPS (reverse proxy) as soon as logins travel over a network. Idle sessions close after 30 minutes.
|
|
730
|
+
|
|
731
|
+
---
|
|
732
|
+
|
|
733
|
+
## Example prompts
|
|
609
734
|
|
|
610
735
|
**Workspaces:**
|
|
611
736
|
- *"Which Huly workspaces do I have?"*
|
|
@@ -663,7 +788,7 @@ For network access (HTTP/SSE) use the [Docker image](#docker-network-reachable-s
|
|
|
663
788
|
|
|
664
789
|
---
|
|
665
790
|
|
|
666
|
-
## Document
|
|
791
|
+
## Document content
|
|
667
792
|
|
|
668
793
|
### Reading: `get_document`
|
|
669
794
|
|
|
@@ -753,44 +878,6 @@ Required column: `title`. Optional: `priority` (Urgent/High/Medium/Low), `status
|
|
|
753
878
|
|
|
754
879
|
---
|
|
755
880
|
|
|
756
|
-
## Authentication
|
|
757
|
-
|
|
758
|
-
Create a `.env` file in the project root (or pass via `env` in your client config). No workspace is needed in either option.
|
|
759
|
-
|
|
760
|
-
**Option A — Email + password (recommended):**
|
|
761
|
-
|
|
762
|
-
Works if you have a password set on your Huly account (Profile → Security → Change password).
|
|
763
|
-
|
|
764
|
-
```bash
|
|
765
|
-
HULY_EMAIL=your@email.com
|
|
766
|
-
HULY_PASSWORD=yourpassword
|
|
767
|
-
```
|
|
768
|
-
|
|
769
|
-
**Option B — Token (SSO accounts: Google/GitHub):**
|
|
770
|
-
|
|
771
|
-
```bash
|
|
772
|
-
npm run setup
|
|
773
|
-
```
|
|
774
|
-
|
|
775
|
-
The wizard sends a one-time code to your email, saves the resulting account token as `HULY_TOKEN` in `.env`, and lists the workspaces the account can access (a discovery test).
|
|
776
|
-
|
|
777
|
-
```bash
|
|
778
|
-
HULY_TOKEN=your-token-here
|
|
779
|
-
```
|
|
780
|
-
|
|
781
|
-
A token copied from the browser (DevTools → Application → Local Storage → `token`) also works, but may be scoped to the single workspace open in that tab. If the account service refuses to list workspaces for such a token, the server falls back to that one workspace. Use `npm run setup` for full multi-workspace discovery.
|
|
782
|
-
|
|
783
|
-
> Tokens expire after some time. If you get an auth error, run `npm run setup` again or switch to email + password.
|
|
784
|
-
|
|
785
|
-
**Self-hosted Huly:**
|
|
786
|
-
|
|
787
|
-
```bash
|
|
788
|
-
HULY_ACCOUNTS_URL=https://your-huly-instance.com/_accounts # login + workspace discovery
|
|
789
|
-
HULY_FRONT_URL=https://your-huly-instance.com # document content + file uploads
|
|
790
|
-
```
|
|
791
|
-
|
|
792
|
-
---
|
|
793
|
-
|
|
794
881
|
## Architecture
|
|
795
882
|
|
|
796
883
|
```text
|
|
@@ -813,7 +900,7 @@ HULY_EMAIL + HULY_PASSWORD (or HULY_TOKEN)
|
|
|
813
900
|
- **No current workspace** — there is no global or "last used" workspace; see [Workspaces](#workspaces-one-account-several-workspaces)
|
|
814
901
|
- **Stdio transport** — standard MCP transport; the Docker image adds HTTP/SSE via `mcp-proxy`
|
|
815
902
|
|
|
816
|
-
See [`src/connection.ts`](src/connection.ts).
|
|
903
|
+
See [`src/connection.ts`](https://github.com/JoKeks2023/huly-mcp/blob/main/src/connection.ts).
|
|
817
904
|
|
|
818
905
|
---
|
|
819
906
|
|
|
@@ -834,13 +921,13 @@ GitHub Actions check every pull request:
|
|
|
834
921
|
| `scheduled.yml` | nightly live smoke test against a sandbox workspace; weekly: the latest `@hcengineering/*` packages, and Huly modules that have no tools yet (see `.github/huly-modules-ignore.txt`). Failures open or update an issue |
|
|
835
922
|
| `release.yml` | on a `vX.Y.Z` tag: version and changelog check, tests, personal-data check, `npm publish --provenance` (Trusted Publishing), GitHub release from the changelog section, MCP registry entry |
|
|
836
923
|
|
|
837
|
-
Security reports: see [SECURITY.md](SECURITY.md).
|
|
924
|
+
Security reports: see [SECURITY.md](https://github.com/JoKeks2023/huly-mcp/blob/main/SECURITY.md).
|
|
838
925
|
|
|
839
926
|
`test/repo.test.ts` keeps the docs honest: tool counts in this README, the site and `DOCKERHUB.md` must match the registry, the version must match everywhere, and the plugin must be well-formed.
|
|
840
927
|
|
|
841
928
|
**Releasing:**
|
|
842
|
-
1. Move the `Unreleased`
|
|
843
|
-
2. Bump the version in `package.json`, `server.json`, `plugin/.claude-plugin/plugin.json` and `src/server.ts`. The tests check that they agree.
|
|
929
|
+
1. Move the `Unreleased` entries in `CHANGELOG.md` under `### X.Y.Z — date`.
|
|
930
|
+
2. Bump the version in `package.json`, `server.json`, `plugin/.claude-plugin/plugin.json`, `plugin/.mcp.json` (exact npx version) and `src/server.ts`. The tests check that they agree.
|
|
844
931
|
3. Merge, then tag `vX.Y.Z` on `main`. The rest runs by itself.
|
|
845
932
|
|
|
846
933
|
**Environments and secrets:**
|
|
@@ -856,212 +943,21 @@ Secrets:
|
|
|
856
943
|
|
|
857
944
|
## Changelog
|
|
858
945
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
- **New: `issues_from_document`** — spec → issues in one call: open checklist items of a Huly document (or, without a checklist, its sections) become sub-issues of an epic; checked items are skipped; the document is linked to the epic. Dry run by default.
|
|
862
|
-
- **New: `issues_from_meeting`** — meeting notes → issues in one call: action items (open checkboxes, `TODO:`/`Action:` lines, lists under "Action items"/"Next steps") with `@assignee` and due date taken from the line; dry run first, each new issue linked to the document.
|
|
863
|
-
- **`create_issue` takes `assignee`, `componentLabel` and `milestoneLabel`**, so a new issue no longer needs a second `update_issue` call. An unknown `statusName` is now an error (it used to fall back to the first status). Everything is checked before anything is written.
|
|
864
|
-
- **Unknown tool parameters are rejected instead of silently dropped.** Before, `update_issue {status: "Done"}` answered "No changes made". Now the call fails with the list of valid parameters and nothing is done. Common mix-ups are mapped automatically: `status`→`statusName`, `project`/`projectId`→`projectIdentifier`, `issue`/`issueId`/`id`→`identifier`, `component`→`componentLabel`, `milestone`→`milestoneLabel`.
|
|
865
|
-
- **`get_issue` is shorter:** empty fields (no milestone, 0 comments, …) are left out and the fields share one line.
|
|
866
|
-
- **Smaller tool list:** the `workspace` parameter no longer repeats its description in every tool (the server instructions explain it once). Default set 38.7k → 35.2k characters, all toolsets 88.8k → 80.3k.
|
|
867
|
-
- **New `HULY_TRANSACTOR_URL`:** a server running next to Huly (same Docker network) can reach the transactor internally, e.g. `ws://huly/_transactor`, instead of the public address — no detour through the uplink or a tunnel.
|
|
868
|
-
- **Claude Code plugin: new skill `huly-efficient`** — which Huly call answers which question with the least output (sizes measured on a real project), which writes need only one call, and which checks the tools already do. The `huly-workflow` skill points to it.
|
|
869
|
-
- **Claude Code plugin:** `/huly:standup` and `/huly:triage` (and the MCP prompts) now use the one-call tools `standup` and `triage_inbox`; new commands `/huly:day` (`my_day`) and `/huly:report` (`project_report`); new settings for a pinned workspace (`HULY_WORKSPACE`) and on-demand toolsets (`HULY_DYNAMIC_TOOLSETS`). The skill points to the overview tools and to `create_issue` with component/milestone.
|
|
870
|
-
- **Fixed: Huly client log lines on stdout.** `Client: onConnect 1` landed in the JSON-RPC stream; mcp-proxy logged "Failed to parse JSONRPC message". Such logs now go to stderr.
|
|
871
|
-
- **Fixed: session tokens in logs.** Huly's client logs its websocket URL including the workspace token (`client websocket error: … /_transactor/<token>`), which ended up in `docker compose logs`. Tokens in log output are now masked as `***`.
|
|
872
|
-
- **Fixed: `create_issue_tree` (and `issues_from_document`) left reused issues outside the epic.** A same-title issue that is reused now moves under the epic when it has no parent; one under another parent stays there, and the plan and result say so.
|
|
873
|
-
- **Fixed: blob requests without a timeout.** Reading document/description content and uploads could hang a tool call when the front service stalled. Reads now stop after 30 s, uploads after 2 min, with a clear error naming `HULY_FRONT_URL`.
|
|
874
|
-
- `create_issue_tree` passes component, milestone and assignee straight to `create_issue`, so a wrong name fails before the issue exists (before: the issue was created, then the update failed).
|
|
875
|
-
- Unknown-parameter error of tools without own parameters (e.g. `list_issue_statuses`) said "Valid: ."; it now says the tool takes no parameters besides `workspace`.
|
|
876
|
-
- README: context-cost table re-measured (the pinned saving is now ~10%, not 20%, since the `workspace` description was already shortened).
|
|
877
|
-
- CI: CodeQL Action v4; runs on `main` are no longer cancelled by the next push.
|
|
878
|
-
|
|
879
|
-
### 3.1.1 — 2026-11-04
|
|
880
|
-
|
|
881
|
-
- **Fixed: Docker image behind a reverse proxy.** The `mcp-proxy` update in 3.1.0 made the server reject every Host name except `localhost` (`421 Invalid Host header`). New variable `MCP_ALLOWED_HOSTS` (comma-separated) lists the host names clients use, e.g. `MCP_ALLOWED_HOSTS=huly-mcp.example.com`. Without it the container logs a warning. CI now tests allowed and rejected Host headers.
|
|
882
|
-
- Release workflow: when `npm publish` fails, the OIDC/auth lines of npm's debug log are shown (3.1.0 had to be published to npm by hand).
|
|
883
|
-
|
|
884
|
-
### 3.1.0 — 2026-11-04
|
|
885
|
-
|
|
886
|
-
First 3.x release on npm. 3.0.0 was only released on GitHub; everything from it is included here.
|
|
887
|
-
|
|
888
|
-
**One call instead of several**
|
|
889
|
-
- **New: `my_day`** (toolset `agent`, on by default) — "what's on today?" in one call: calendar, to-dos, my issues, reviews, unread inbox.
|
|
890
|
-
- **New: `standup`, `triage_inbox`, `release_notes`** — one call each instead of several: yesterday/today/blockers, the inbox with what changed since last read, and release notes from a milestone.
|
|
891
|
-
- **New: `project_report`** (toolset `agent`) — weekly report of a project: done, new, in progress, blocked, overdue, PRs, milestones, time logged.
|
|
892
|
-
|
|
893
|
-
**More of Huly**
|
|
894
|
-
- **New: test management, much more of it** — `import_test_results` and the CLI `huly-mcp junit` bring CI results (JUnit XML) into Huly as test runs; `get_test_report` shows failing, flaky, blocked and never-run cases over the latest runs; `create_issue_from_test_result` turns a failed test into a bug (steps and failure included, related to the test case); `create_test_cases` creates many cases at once; suites can be renamed, moved and deleted, runs renamed, dated and deleted, plans deleted, results assigned.
|
|
895
|
-
- **New: `start_process` / `cancel_execution`** — run a process on a card and cancel a running one. Starting works like Huly's "Run process" menu; Huly's process service then moves the execution on. Processes whose start asks for input in the app are refused, and so is a second run where the process forbids parallel runs. Cancelling asks first.
|
|
896
|
-
- `get_issue` names related non-issue documents (e.g. a test case) instead of showing a bare id.
|
|
897
|
-
|
|
898
|
-
**Changed behaviour**
|
|
899
|
-
- **Changed: `list_issues` lists open issues by default.** Pass `status: "all"` for every issue, or a status name. Long lists show `51–100 of 118` and page with `offset`. In a mature project this cuts the answer by ~80%.
|
|
900
|
-
- **Changed: `list_comments` returns the newest comments** (before: the oldest), still in chronological order. Comments over 1,500 characters are shortened with a visible marker; `full: true` shows them whole. Issue descriptions are never shortened, because `update_issue` replaces them.
|
|
901
|
-
- **Changed: Docker tags.** `latest` now means the latest *release* (before: the latest commit on `main`), and `main` builds are tagged `edge`. There are new tags `3` and `3.1` for release lines, and images are built for `linux/arm64` as well, with an SBOM and provenance.
|
|
902
|
-
- `list_labels`: dead code for the ignored `projectIdentifier` removed. No behaviour change.
|
|
903
|
-
|
|
904
|
-
**Fewer tokens**
|
|
905
|
-
- **Fewer tokens:**
|
|
906
|
-
- With `HULY_WORKSPACE` set, tools take no `workspace` argument (−20% tool-list size). Changes still go to exactly that workspace.
|
|
907
|
-
- Validation limits (`minLength`, `maximum` …) are no longer sent in tool schemas. They are still enforced, with a clear error.
|
|
908
|
-
- `list_issues` uses one line per issue and leaves out "No priority".
|
|
909
|
-
- `list_notifications` shows notification ids only with `ids: true`. Marking read by object (`PROJ-12`) does not need them.
|
|
910
|
-
- **New: load toolsets on demand** (`HULY_DYNAMIC_TOOLSETS=1`, opt-in): start small and let Claude load toolsets with `enable_toolsets`. With `agent,inbox` a session starts at ≈1.8k tokens. Not yet verified in Claude Desktop.
|
|
911
|
-
- Server instructions are 41 % shorter (1,463 → 858 chars). They now point to the one-call overviews (`my_day`, `standup`, `triage_inbox` …); hints that the tool descriptions already carry were dropped.
|
|
912
|
-
- Read tools describe `workspace` more briefly (the rule for omitting it is in the server instructions), which keeps the default set within its context budget.
|
|
913
|
-
|
|
914
|
-
**Security**
|
|
915
|
-
- **Security fixes from code scanning:**
|
|
916
|
-
- Docker image: `mcp-proxy` 0.14.0 with `mcp` 1.30.0 (fixes 5 CVEs); npm is removed from the runtime image (23 alerts in npm's bundled packages); Debian security updates are applied at build time.
|
|
917
|
-
- `uuid` is pinned to 11.1.1 via an npm override (a CVE in 8.3.2, pulled in by Huly's server client).
|
|
918
|
-
- Code: entity decoding in `triage_inbox` no longer double-unescapes (`&lt;` stays `<`); JUnit comment removal is repeated until nothing is left; a check-then-read race in `huly-mcp-setup` is gone.
|
|
919
|
-
|
|
920
|
-
**CI and releases**
|
|
921
|
-
- **CI and automation:**
|
|
922
|
-
- every PR is checked on three platforms, with a token report, a personal-data check, a Docker scan and CodeQL
|
|
923
|
-
- releases publish themselves from a tag
|
|
924
|
-
- a nightly live test runs against a sandbox workspace
|
|
925
|
-
- weekly checks cover new Huly packages and Huly modules without tools
|
|
926
|
-
- see [Development and CI](#development-and-ci)
|
|
927
|
-
|
|
928
|
-
### 3.0.0 — 2026-11-04
|
|
929
|
-
|
|
930
|
-
One large release instead of several small ones, built in stages (see [#11](https://github.com/JoKeks2023/huly-mcp/issues/11)).
|
|
931
|
-
|
|
932
|
-
Breaking:
|
|
933
|
-
- Tools are grouped into toolsets.
|
|
934
|
-
- `calendar`, `github`, `generic-write` and `tracker-admin` are not enabled by default.
|
|
935
|
-
- `HULY_TOOLSETS=all` enables everything.
|
|
936
|
-
|
|
937
|
-
**Toolsets and the core modules**
|
|
938
|
-
- **New: toolsets** (`HULY_TOOLSETS`) and slimmer tool schemas. The 64 tools of 2.2.0 now cost about 36 % fewer tokens.
|
|
939
|
-
- **New: inbox** — `list_notifications`, `mark_notifications_read`
|
|
940
|
-
- **New: activity** — `get_activity`
|
|
941
|
-
- **New: planner** — `list_todos`, `create_todo`, `update_todo`, `delete_todo`, `schedule_todo`
|
|
942
|
-
- **New: calendar** — `list_events`, `create_event`, `update_event`, `delete_event`
|
|
943
|
-
- **New: chat** — `list_thread`, `reply_to_message`, `update_message`, `delete_message`, `add_reaction`, `remove_reaction`, `pin_message`. `list_messages` now shows authors and message ids.
|
|
944
|
-
- **New: GitHub** — `list_pull_requests`, `get_pull_request`
|
|
945
|
-
- **New: persons** — `list_persons`, `get_person`, `create_person`, `update_person`, `add_contact_channel`, `remove_contact_channel`
|
|
946
|
-
- **New: generic access** — `list_classes`, `describe_class` and `query_documents` (secrets redacted). `generic_create`, `generic_update` and `generic_delete` are opt-in and run as a dry run by default.
|
|
947
|
-
|
|
948
|
-
**Agent workflow**
|
|
949
|
-
- **New: agent workflow** (toolset `agent`, on by default) — `get_issue_context`, `start_work`, `finish_work`, `create_issue_tree`, `changes_since`, `claim_issue`, `release_issue`, `find_project_for_repo`
|
|
950
|
-
- **New: MCP resources** (`huly://…/issue/…`, `huly://…/document/…`)
|
|
951
|
-
- **New: MCP prompts** (`start`, `finish`, `plan`, `triage`, `standup`)
|
|
952
|
-
- **New: guard rails** — `HULY_WRITE_PROJECTS` limits changes to the listed projects, and `HULY_AUDIT_LOG` records every change.
|
|
953
|
-
- **Changed: toolset `tracker-admin`.** These tools are no longer in the default set: `create_project`, `update_project`, `create_issue_status`, `update_label`, `delete_label`, `delete_milestone`, `delete_component`, `repair_parent_links`. Enable them with `HULY_TOOLSETS=…,tracker-admin` or `all`.
|
|
954
|
-
|
|
955
|
-
**Claude Code plugin**
|
|
956
|
-
- **New: Claude Code plugin** (`/plugin marketplace add JoKeks2023/huly-mcp`, `/plugin install huly@huly-mcp`). It bundles:
|
|
957
|
-
- the MCP server with its settings
|
|
958
|
-
- the `huly-workflow` skill
|
|
959
|
-
- session-start and PR hooks
|
|
960
|
-
- the commands `/huly:start`, `/huly:finish`, `/huly:plan`, `/huly:triage`, `/huly:standup`
|
|
961
|
-
|
|
962
|
-
**More of Huly**
|
|
963
|
-
- **New: fulltext search across everything** — `search` (issues, documents, messages, cards, files, persons …)
|
|
964
|
-
- **New: toolset `collaboration`** — followers of issues/documents, public guest links, document comments
|
|
965
|
-
- **New: toolset `cards`** — card types and tags, cards with content, nesting and field values
|
|
966
|
-
- **New: toolset `fields`** — custom fields on issues, project types, card types or any class, and their values
|
|
967
|
-
- **New: toolset `drive`** — drives, folders, versioned files (upload, download, move, restore)
|
|
968
|
-
- **New: toolset `templates`** — issue templates; new issue with sub-issues from a template
|
|
969
|
-
- **New: toolset `testing`** — test projects, suites, cases, plans, runs and results
|
|
970
|
-
- **New: toolset `products`** — products and versions (read-only)
|
|
971
|
-
- **New: label categories** (`tracker-admin`)
|
|
972
|
-
- **New: documents** — `list_documents` shows the whole tree; `update_document` renames and moves (also to another teamspace); new documents are placed after their siblings
|
|
973
|
-
- **New: MCP argument completions** for prompts and `huly://` resources (workspaces, projects, issue ids) and **resource subscriptions** (`notifications/resources/updated` when a subscribed issue or document changes)
|
|
974
|
-
|
|
975
|
-
**Business modules**
|
|
976
|
-
- **New: toolsets `members`, `recruiting`, `crm`, `hr`, `inventory`** — invitations and roles, vacancies/candidates/applications, leads/customers, departments and time off, inventory
|
|
977
|
-
- **New: message templates** (`templates`) and **project types with workflows** (`tracker-admin`)
|
|
978
|
-
- **New, read-only: `meetings`** (minutes, transcripts), **`qms`** (controlled documents, trainings), **`process`**, **`surveys`**
|
|
979
|
-
- Not included: Huly's Board module (hidden and off by default in Huly itself).
|
|
980
|
-
|
|
981
|
-
**Agents**
|
|
982
|
-
- **New: confirmation for risky tools** — deletes, bulk updates, moves, generic writes, revoking links and restoring file versions ask the user via MCP elicitation when the client supports it (`HULY_CONFIRM`). Declining changes nothing.
|
|
983
|
-
- **New: `huly-mcp watch`** — Huly hands work to an agent: issues with a label or assigned to the agent's own account are claimed, passed to `claude -p` (or any command) and released afterwards. Runs are unattended, so they default to `HULY_CONFIRM=strict`.
|
|
984
|
-
|
|
985
|
-
**Fixes**
|
|
986
|
-
- `create_teamspace`, `create_channel`, `start_direct_message` and `create_project` stored the user's social id as member/owner; Huly 0.7 expects the account id. Spaces created with earlier versions may list you twice as member and have no proper owner.
|
|
987
|
-
- Public links created on servers whose `FRONT_URL` is `localhost` are shown with `HULY_FRONT_URL` instead.
|
|
988
|
-
- Empty or unresolved `HULY_*` variables (for example plugin settings left blank) now count as not set.
|
|
989
|
-
- Nested tool errors no longer repeat the "Huly MCP:" prefix.
|
|
990
|
-
|
|
991
|
-
### 2.2.0 — planning, bulk edits, fixes for Huly 0.7
|
|
992
|
-
|
|
993
|
-
- **New: filters in `list_issues`** — milestone, component, label, assignee, parent (null = without / top-level)
|
|
994
|
-
- **New: `bulk_update_issues`, `move_issue`, `list_sub_issues`, `list_time_reports`**
|
|
995
|
-
- **New: `update_project`, `update_comment`, `update_label`, `delete_label`, `remove_relation`, `remove_blocked_by`**
|
|
996
|
-
- **New: `repair_parent_links`** — re-links sub-issues created by earlier versions (dry run by default)
|
|
997
|
-
- **More detail in `get_issue`** — assignee, milestone, component, labels, parent, blocked by, related
|
|
998
|
-
- **`list_members`** shows names
|
|
999
|
-
- **Fix: `set_parent`** now links like Huly itself (`attachedTo`). Before, sub-issues did not appear under their parent in Huly. Existing links: `repair_parent_links` or `set_parent` again
|
|
1000
|
-
- **Fix: people lookup on Huly 0.7** — `log_time` failed ("Could not identify current user"), assigning by name (`assignee`, `lead`) never matched and comment authors showed as "Unknown". People are now resolved via the Employee mixin; names are shown as "First Last" and ambiguous names are rejected
|
|
1001
|
-
- **Fix: bold/italic text** in issue, document and organization descriptions no longer breaks into separate lines
|
|
1002
|
-
- **Fix: `update_issue`** accepts `componentLabel: null` (as documented) and rejects invalid due dates
|
|
1003
|
-
|
|
1004
|
-
### 2.1.0 — milestones & components, security updates
|
|
1005
|
-
|
|
1006
|
-
- **New: `get_milestone`, `update_milestone`, `delete_milestone`** — progress overview, edit name/date/status/description, delete with issues unassigned or moved via `moveIssuesTo`
|
|
1007
|
-
- **New: `update_component`, `delete_component`** — edit name/description/lead, delete with issues unassigned or moved via `moveIssuesTo`
|
|
1008
|
-
- **Changed: `list_components`** renders Markdown/ProseMirror descriptions as text
|
|
1009
|
-
- **Security:** all open dependency advisories fixed — `@modelcontextprotocol/sdk` 1.32, `ws` 8.22, `zod` 4, `dompurify` 3.4.17 (override)
|
|
1010
|
-
|
|
1011
|
-
### 2.0.0 — multi-workspace
|
|
1012
|
-
|
|
1013
|
-
Breaking: tools that change data require `workspace`; `HULY_WORKSPACE` only restricts the server to one workspace.
|
|
1014
|
-
|
|
1015
|
-
- **New: multi-workspace support** — one account login, workspaces discovered via `getUserWorkspaces()`, one cached connection per workspace; `HULY_WORKSPACE` is no longer required (still honoured as an optional single-workspace restriction)
|
|
1016
|
-
- **New: `list_workspaces`**
|
|
1017
|
-
- **Changed: every tool takes `workspace`** — required for all tools that change data; reads may omit it only when exactly one workspace is available
|
|
1018
|
-
- **New: `huly-mcp-selfhost` bin alias** — `npx huly-mcp-selfhost` now starts the server directly
|
|
1019
|
-
- **Changed: `npm run setup`** no longer asks for a workspace; it lists the discovered workspaces instead
|
|
1020
|
-
- **Changed: `scripts/import-csv.js`, `cleanup-issues.js`, `demo.js`** need `--workspace=<slug>` (or `HULY_WORKSPACE`)
|
|
1021
|
-
|
|
1022
|
-
### Fork — self-hosted support, chat, attachments, statuses, organizations
|
|
1023
|
-
- **Fix: self-hosted document/description writes** — auto-detects `huly-selfhost` via `HULY_FRONT_URL` and uploads through `front`'s `/files` contract instead of Huly Cloud's datalake, which self-hosted doesn't run
|
|
1024
|
-
- **New: `description` on `create_issue`/`update_issue`** — was missing entirely upstream
|
|
1025
|
-
- **New: Chat** — `list_channels`, `create_channel`, `start_direct_message`, `send_message`, `list_messages`
|
|
1026
|
-
- **New: Attachments** — `attach_file`, `list_attachments`, `delete_attachment`
|
|
1027
|
-
- **New: Issue Statuses** — `list_issue_statuses`, `create_issue_status`
|
|
1028
|
-
- **New: Organizations** — `list_organizations`, `get_organization`, `create_organization`, `update_organization`
|
|
1029
|
-
- See [About this fork](#about-this-fork) for details and what was investigated but not built
|
|
1030
|
-
|
|
1031
|
-
### v0.5.6 — delete_document
|
|
1032
|
-
- **New: `delete_document`** — permanently delete a document by ID
|
|
1033
|
-
|
|
1034
|
-
### v0.5.5 — create_teamspace
|
|
1035
|
-
- **New: `create_teamspace`** — create a new document teamspace (top-level folder for organising documents by project or team)
|
|
1036
|
-
|
|
1037
|
-
### v0.5.2 — delete_comment + link_document
|
|
1038
|
-
- **New: `delete_comment`** — delete a specific comment from an issue by ID; `list_comments` now includes comment IDs in its output
|
|
1039
|
-
- **New: `link_document`** — link a Huly document to an issue; the document appears in the Relations panel on the issue
|
|
1040
|
-
|
|
1041
|
-
### v0.5.0 — Document Writing + Bug Fixes
|
|
1042
|
-
- **New: `update_document`** — write Markdown to any Huly document programmatically; `\`\`\`mermaid` blocks use Huly's native node type and render as interactive diagrams
|
|
1043
|
-
- **Fix: `IssueStatus` queries** — statuses are stored globally in Huly (`core:space:Model`), not per-project; removed incorrect space filter that caused *"no statuses found"* errors on `create_issue`, `update_issue`, and `list_issues`
|
|
1044
|
-
- **Fix: `create_project`** — sets `members: [currentUser]` so newly created projects are immediately visible in the Huly UI
|
|
1045
|
-
|
|
1046
|
-
### v0.4.0
|
|
1047
|
-
- `log_time`, `list_comments`, component/milestone assignment on `update_issue`
|
|
1048
|
-
|
|
1049
|
-
### v0.3.1
|
|
1050
|
-
- `get_document`, `create_document`
|
|
1051
|
-
|
|
1052
|
-
### v0.3.0
|
|
1053
|
-
- `create_project`, `create_milestone`, assignee support on issues
|
|
946
|
+
See [CHANGELOG.md](https://github.com/JoKeks2023/huly-mcp/blob/main/CHANGELOG.md).
|
|
1054
947
|
|
|
1055
948
|
---
|
|
1056
949
|
|
|
1057
|
-
##
|
|
950
|
+
## Credits
|
|
1058
951
|
|
|
1059
|
-
|
|
1060
|
-
- Upstream: https://github.com/varaprasadreddy9676/huly-mcp ([npm](https://www.npmjs.com/package/huly-mcp-sdk), [MCP Registry](https://registry.modelcontextprotocol.io) — neither reflects this fork's changes)
|
|
1061
|
-
- Missing `.d.ts` in `@hcengineering/*` 0.7.411+: https://github.com/hcengineering/platform/issues/10881
|
|
952
|
+
Started as a fork of [varaprasadreddy9676/huly-mcp](https://github.com/varaprasadreddy9676/huly-mcp) (npm `huly-mcp-sdk`) by SaiVaraprasad Medapati and grown from its 33 tools to 226, with self-hosted support, toolsets, agent workflow and the Claude Code plugin. Published separately as `huly-mcp-selfhost`. Not affiliated with Huly Labs.
|
|
1062
953
|
|
|
1063
|
-
|
|
954
|
+
## Links
|
|
955
|
+
|
|
956
|
+
- Website: https://jokeks2023.github.io/huly-mcp/
|
|
957
|
+
- Source and issues: https://github.com/JoKeks2023/huly-mcp
|
|
958
|
+
- npm: https://www.npmjs.com/package/huly-mcp-selfhost · Docker: https://hub.docker.com/r/jokeks2023/huly-mcp · MCP Registry: `io.github.jokeks2023/huly-mcp-selfhost`
|
|
959
|
+
- Security: [SECURITY.md](https://github.com/JoKeks2023/huly-mcp/blob/main/SECURITY.md)
|
|
1064
960
|
|
|
1065
961
|
## License
|
|
1066
962
|
|
|
1067
|
-
[Eclipse Public License 2.0](https://
|
|
963
|
+
[Eclipse Public License 2.0](https://github.com/JoKeks2023/huly-mcp/blob/main/LICENSE)
|