huly-mcp-selfhost
Surfaces GitHub pull requests alongside Huly work items: PRs appear in one-call overviews such as my_day and project_report, the /huly:finish command (and finish_work tool) links a PR to its issue and moves it to review, and session-start/post-gh pr create/gh pr merge hooks map branches like proj-12-login to issues and remind agents to link PRs or check statuses after merges.
huly-mcp-selfhost
Huly for AI agents. An MCP server for Huly — 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. 227 tools, built for agent workflows and to spend as few tokens as possible.
Website · Quick start · Tools · Claude Code plugin · Changelog
Highlights
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.
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, andhuly-mcp watchto hand issues to Claude from Huly.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.
Safe by default: every change names its workspace, risky tools ask first, writes can be limited to projects, optional audit log — and
undo_changesreverses your last changes.Small and quick to install: one self-contained package of ~4 MB (900 kB download) — no 180 dependencies to fetch on the first
npx.No telemetry. The server talks to your Huly server and nothing else: no analytics, no usage tracking, nothing to opt out of. (The only other request, the npm version check, runs when you call
check_setup.)Claude Code plugin:
/huly:setupasks once per repo how Huly is used there and writes the rules; skill, hooks and/huly:*commands. Guides and asetupprompt for every other MCP client too.Self-hosted first: document and description content, file uploads and internal URLs work on
huly-selfhost; one account, all its workspaces.
Related MCP server: huly-mcp
Tokens, measured
What the model reads — measured on a real self-hosted project (≈60 issues):
Characters | ≈ Tokens | |
Tool list, default toolsets (99 tools, each callable directly) | 38,259 | 10.9k |
Tool list, pinned workspace | 34,567 | 9.9k |
Open issues of a project (one call, ≈30 issues) | 2,768 | 0.8k |
One issue with description | 318 | 0.1k |
Project report (done, in progress, blocked, milestones, PRs, time) | ~2,700 | 0.8k |
My day (calendar, to-dos, my issues, PRs, inbox) | ~1,200 | 0.3k |
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.
Compared with another popular Huly MCP server
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.
Question | huly-mcp-selfhost | Other server | Ratio |
Open issues of a project | 2,768 (1 call) | 11,601 (3 calls) | 4.2× less |
Issues in progress | 211 (1 call) | 790 (1 call) | 3.7× less |
One issue | 318 (1 call) | 585 (1 call) | 1.8× less |
Everything about an issue (fields, sub-issues, comments, relations) | 1,246 (1 call) | 3,585 (4 calls) | 2.9× less |
Search | 406 (1 call) | 1,405 (1 call) | 3.5× less |
Projects | 550 (1 call) | 1,041 (1 call) | 1.9× less |
Milestones | 208 (1 call) | 503 (1 call) | 2.4× less |
Components | 1,302 (1 call) | 692 (1 call) | 2.0× more |
Documents of a teamspace | 106 (1 call) | 305 (1 call) | 2.9× less |
Tool definitions (49 tools with the same name) | 15,728 | 216,890 | 13.8× less |
Quick start
You need Node.js 20+ and a Huly account — Huly Cloud or self-hosted.
Claude Code — install the plugin, then fill in its settings when asked:
/plugin marketplace add JoKeks2023/huly-mcp
/plugin install huly@huly-mcpThen run /huly:setup in a repository. Details: Claude Code plugin.
Claude Desktop, Cursor, VS Code, Windsurf, Zed, … — add the server to your client's MCP config:
{
"mcpServers": {
"huly": {
"command": "npx",
"args": ["-y", "huly-mcp-selfhost"],
"env": {
"HULY_EMAIL": "you@example.com",
"HULY_PASSWORD": "your-password"
}
}
}
}Self-hosted Huly: add
"HULY_ACCOUNTS_URL": "https://huly.example.com/_accounts"and"HULY_FRONT_URL": "https://huly.example.com".Google/GitHub login (no password): run
npx huly-mcp-selfhost setupand useHULY_TOKENinstead — see Authentication.One workspace? Add
"HULY_WORKSPACE": "<slug>"— fewer tokens.
Config file locations and examples for each client: Compatible clients.
Server for a team or remote clients — huly-mcp-selfhost http or the Docker image; everyone logs in with their own Huly account in the browser (OAuth): see Team server over HTTP.
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.
Claude Code plugin
The repo is also a Claude Code plugin marketplace. The plugin bundles the MCP server with a workflow skill, hooks and commands:
/plugin marketplace add JoKeks2023/huly-mcp
/plugin install huly@huly-mcpNote: the plugin starts the npm package at exactly its own version (e.g.
huly-mcp-selfhost@3.5.1; 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 pointplugin/.mcp.jsonatdist/index.jsand startclaude --plugin-dir ./plugin.
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).
Part | What it does |
MCP server |
|
Skill | How to use Huly while coding at the lowest token cost: the repo's |
Hook on session start | Reports the GitHub repo and branch; a branch like |
Hook after | Reminds Claude to link the new PR to its issue ( |
| 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 |
| Pick up an issue (from the argument or the branch), load the context, plan |
| Honest summary, PR link, status to review |
| Plan → epic + sub-issues (dry run first) |
| My day, stand-up, inbox triage — one call each ( |
| Project status: progress, milestones, blockers ( |
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.
Command line
Every tool also works from the terminal — for scripts, CI and quick looks without a chat. Same login (HULY_* environment or --env-file), same safety rules (write scope, audit log, confirmation for hard-to-undo changes).
npm install -g huly-mcp-selfhost # or: npx huly-mcp-selfhost <command>
huly-mcp tools issue # find tools
huly-mcp help list_issues # parameters, types, allowed values, defaults
huly-mcp get_issue PROJ-12 # one required parameter can be given directly
huly-mcp list_issues --project PROJ --due overdue --assignee null
huly-mcp create_issue -w acme --project PROJ --title "Fix login" --description-file notes.md
huly-mcp bulk_update_issues --identifiers PROJ-1 --identifiers PROJ-2 --status-name Done --yes
huly-mcp my_day --format json | jq -r .textParameters come from the same schemas the MCP server sends to Claude, so
helpis always current. Names work as--project-identifieror--projectIdentifier; common short forms (--project,--status,--milestone, …) too. Values are read by type: numbers,true/false,nullto clear, repeat a flag for lists, JSON for nested values.--json '{…}'or--input file.json(-= stdin) pass everything at once;--<text-param>-filereads a text value from a file.Hard-to-undo tools (deletes, bulk changes, moves) ask in a terminal; in scripts they run only with
--yes.Exit codes: 0 ok · 1 the tool failed or was cancelled · 2 wrong usage (unknown tool or option — with a "did you mean …").
Output: the tool's Markdown;
--format jsongives{"ok", "tool", "text"}(errors too). The Huly SDK's own logging is silenced;HULY_DEBUG=1shows it on stderr.Shell completion for tools, options and allowed values:
eval "$(huly-mcp completion zsh)"(orbash) in your shell profile.
Tools (227 total, grouped in toolsets)
All tools except list_workspaces take a workspace argument — required for every change, optional for reads when only one workspace is available.
Toolsets
Every tool schema is sent to the model in each session (Claude Desktop loads all of them up front), so tools are grouped and only the default toolsets are enabled unless you choose otherwise:
HULY_TOOLSETS=all # everything
HULY_TOOLSETS=tracker,documents,planner # just these ('core' = list_workspaces, check_setup and undo_changes, always on)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.
Toolset | Default | Tools | Contents |
| ✓ | 14 | agent workflow: my day at a glance, standup, project report, release notes, issue context in one call, start/finish work, plan → issue tree, spec document → issues, meeting notes → issues, changes since, claims, repo → project — plus resources and prompts |
| ✓ | 37 | projects, issues, comments, time, labels, relations, milestones, components, statuses, attachments, search |
| ✓ | 8 | teamspaces and documents (tree, move, rename) |
| ✓ | 12 | channels, DMs, threads, edit/delete, reactions, pins |
| ✓ | 11 | members, organizations, persons, contact channels |
| ✓ | 4 | notifications, triage (what changed since last read), mark read/archive; pin, hide, mark unread, follow/unfollow per object |
| ✓ | 1 | change history of an issue/object |
| ✓ | 5 | to-dos, time blocking |
| ✓ | 4 | fulltext search across everything, read any Huly class |
| 12 | rarely needed admin: create/update project, create status, update/delete label, label categories, delete milestone/component, repair parent links, project types and workflows | |
| 4 | calendar events | |
| 2 | pull requests synced by Huly's GitHub integration (read-only) | |
| 3 | create/update/delete any class — dry run by default, deletes need | |
| 8 | followers (collaborators) of issues/documents, public guest links, document comments | |
| 8 | cards: types and tags, create/edit/move/delete, nesting, field values | |
| 3 | custom fields on issues, project types, card types or any class; set values | |
| 10 | drives, folders, versioned files: upload, download, move, restore versions | |
| 11 | issue templates with sub-issues, new issue from template; message templates | |
| 23 | test management: projects, suites, cases, plans, runs, results; JUnit import, report, bugs from failed tests | |
| 2 | products and versions (read-only) | |
| 4 | workspace settings, invite links and e-mails, member roles | |
| 9 | vacancies, candidates, applications | |
| 5 | leads, customers | |
| 7 | departments, staff, vacation/sick/remote days | |
| 5 | categories, products, variants (SKU) | |
| 2 | office rooms, meeting minutes and transcripts (read-only) | |
| 4 | controlled documents and trainings (read-only) | |
| 4 | process definitions and executions; start and cancel | |
| 2 | surveys and aggregated poll answers (read-only) |
Context cost of tools/list (≈3.5 chars/token):
default (99 tools) |
| |
several workspaces | ~38.3k chars ≈ 10.9k tokens | ~83.5k chars ≈ 23.9k tokens |
pinned with | ~34.6k chars ≈ 9.9k tokens | ~75.0k chars ≈ 21.4k tokens |
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.
Agent workflow
Tools, resources and prompts for AI agents working on Huly issues (toolset agent):
Tool | What it does |
| Today (or |
| What I did since the last working day (Monday → Friday, or |
| Release notes from a milestone: done issues as "New and changed" and "Fixes" (by title or label, English and German), merged PR numbers, epics left out; open issues listed separately |
| Weekly (or |
| Everything about an issue in one call: fields, description, parent chain, sub-issues, blocked by / blocks, related, PRs, comments, suggested branch name |
| Status → In Progress, assign to me, optionally claim — returns the full context |
| Work summary as comment, PR ( |
| Plan → epic + sub-issues with priorities, components, milestones, assignees, labels and blockers ( |
| Spec → issues: the open checklist items of a Huly document (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; one call instead of reading the document and repeating every task |
| Meeting notes → issues: open checkboxes, lines starting with |
| Issues/PRs changed since |
| Workspace + project linked to a GitHub repo ( |
| Lease an issue to an agent (label |
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.
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 …).
Guard rails (environment):
Variable | Effect |
| Changes are only allowed when every project they touch (project keys and |
| Every change is appended as one JSON line (time, tool, shortened arguments, success, first line of the result) |
| Default agent name for claims |
| Deletes and other hard-to-undo tools ( |
Huly hands work to Claude: huly-mcp watch
huly-mcp watch turns Huly into the place where you give Claude work. It polls for open issues that carry a label (--label claude) or are assigned to the account it runs as (--assigned, the default), and for each one:
claims the issue (
claim_issue), so a second watcher or agent skips it,runs a command for it — by default
claude -pin the current directory, with this MCP server attached and a prompt that says: read the issue, do the work, hand back withfinish_work,releases the claim if the run did not (
finish_workreleases it), and comments on the issue if the run failed or timed out.
cd ~/code/my-repo
npx huly-mcp-selfhost watch --workspace acme --project WEB --label claude --dry-run # what would run
npx huly-mcp-selfhost watch --workspace acme --project WEB --label claude # poll every 60 sEach issue runs once. A state file (
~/.huly-mcp/watch-<workspace>.json) remembers it. To run it again, remove the label and add it again.The command is yours.
--commandtakes any program; the placeholders{prompt}{issue}{title}{workspace}{agent}{trigger}{mcpConfig}are filled in per argument — no shell is involved, so issue titles cannot inject shell commands. The run also getsHULY_ISSUE,HULY_ISSUE_TITLEandHULY_WORKSPACEin its environment. Examples: a GitHub Action (--command "gh workflow run agent.yml -f issue={issue}"), or Claude with more tools (--command "claude -p {prompt} --mcp-config {mcpConfig} --allowedTools mcp__huly,Bash(npm test),Edit").Default command:
claude -p {prompt} --mcp-config {mcpConfig} --strict-mcp-config --allowedTools mcp__huly --permission-mode acceptEdits.{mcpConfig}is a temporary MCP config that starts this server limited to the watched workspace; the credentials are passed through the environment, not written to the file.Unattended means careful. Runs get
HULY_CONFIRM=strictunless you set it: deletes and other risky tools are refused, because nobody is there to confirm them.HULY_WRITE_PROJECTSlimits which projects are watched and changed. Issue text reaches the agent as instructions — only watch projects whose writers you trust.Its own identity. Give the agent its own Huly account (invite e.g.
claude@your-domainto the workspace) and start the watcher with that account's credentials (--env-file agent.envwithHULY_EMAIL/HULY_PASSWORDorHULY_TOKEN). Then you hand work to Claude by assigning an issue to that user, and every comment, status change and claim shows up under its name instead of yours.--agent <name>(orHULY_AGENT_NAME) names it in claims.Other options:
--interval <sec>,--timeout <min>(default 60),--once,--cwd <dir>,--prompt <template>,--state <file>.huly-mcp watch --helplists them all.
CI test results into Huly: huly-mcp junit
huly-mcp junit report.xml --project "App" imports a JUnit XML report as a test run in Huly's test management. Almost every test runner writes JUnit XML (Jest/Vitest with a JUnit reporter, pytest --junitxml, go-junit-report, Gradle, Maven Surefire, xcpretty). Suites and cases that do not exist yet are created; failed tests keep their message and stack trace. Then ask Claude "What is flaky in App?" (get_test_report) or "File bugs for today's failures in PROJ" (create_issue_from_test_result).
# .github/workflows/test.yml (after the test step)
- name: Report to Huly
if: always()
run: npx -y huly-mcp-selfhost junit reports/junit.xml --project "App" --run "CI ${{ github.ref_name }} #${{ github.run_number }}"
env:
HULY_URL: ${{ secrets.HULY_URL }}
HULY_TOKEN: ${{ secrets.HULY_TOKEN }}
HULY_WORKSPACE: my-workspaceOptions: --run <name>, --parent-suite <suite>, --no-create (only existing cases), --fail-on-failures (exit code 1 when tests failed), --dry-run, --workspace. huly-mcp junit --help lists them.
Tool reference
Category | Tool | Description |
Workspaces |
| List the workspaces this account can access (name, slug, id) |
| Undo your last changes made through this server, newest first: what was created is removed, changed fields get their old values, deleted objects come back with the same id and data. Dry run by default; skips (and says so) when someone changed the object since — | |
| 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 | |
Projects |
| List all projects in a workspace |
| Get project details + available statuses | |
| Create a new tracker project with a unique identifier (tracker-admin) | |
| Change name, description, default assignee or default status (tracker-admin) | |
Issues |
| List issues — open ones by default ( |
| Full details of an issue (e.g. | |
| Create a new issue (with optional Markdown description) | |
| Update title, description, status, priority, assignee, due date, component, milestone | |
| Permanently delete an issue by identifier | |
| Same change on many issues at once — validates all before writing | |
| Move an issue (with sub-issues, comments, attachments, labels, time) to another project | |
| Sub-issue tree of an epic with status and progress | |
Comments |
| Add a comment to an issue |
| Newest comments on an issue, oldest first (includes IDs for | |
| Edit a comment | |
| Delete a specific comment by ID | |
Time Tracking |
| Log hours spent on an issue |
| Logged time per issue or project, totals per member, member/date filters | |
Labels |
| List all labels with color + usage count |
| Create a new label with an optional hex color | |
| Add a label to an issue (auto-creates if it doesn't exist) | |
| Remove a label from an issue | |
| Rename or recolor a label (updated on every issue) (tracker-admin) | |
| Delete a label and remove it from every issue (tracker-admin) | |
Relations |
| Mark two issues as related (bidirectional) |
| Mark an issue as blocked by another issue | |
| Set or clear the parent epic of an issue | |
| Remove a "related" link | |
| Remove a "blocked by" link | |
| Fix sub-issues linked by huly-mcp ≤ 2.1 that don't show under their parent (dry run by default) (tracker-admin) | |
Members |
| List workspace members with names and roles |
Persons ( |
| Contact persons with their channels |
| Person details, contact channels, organizations | |
| Create a contact person (with optional channels) | |
| Change name or city | |
| Add email, phone, LinkedIn, … | |
| Remove a contact channel | |
Milestones |
| List milestones for a project |
| Create a milestone with a target date and status | |
| Milestone details with progress (done/open/canceled issues) and the open issues | |
| Change name, target date, status or description | |
| Delete a milestone; its issues are unassigned or moved ( | |
Components |
| List components (sub-areas) in a project |
| Create a new component with optional lead | |
| Change name, description or lead | |
| Delete a component; its issues are unassigned or moved ( | |
Documents |
| List document teamspaces |
| Create a new teamspace (top-level document folder) | |
| List documents in a teamspace | |
| Permanently delete a document by ID | |
| Get document metadata + content | |
| Create a new document in a teamspace | |
| Write Markdown content to a document — Mermaid diagrams render natively | |
| Link a document to an issue — appears in the Relations panel | |
| Shows the full document tree; | |
Search |
| Full-text search across all issues of a workspace |
| Full-text search across everything — issues, documents, messages, cards, files, persons … ( | |
Chat |
| List all channels in the workspace |
| Create a new channel | |
| Start (or find) a 1:1 direct message with a workspace member | |
| Send a message to a channel or direct message | |
| List messages with authors, ids, replies, reactions, pins | |
| A message with its thread replies | |
| Reply in a thread (channel messages and issue comments) | |
| Edit a message or reply | |
| Delete a message or reply | |
| Emoji reactions | |
| Pin or unpin a message | |
Attachments |
| Attach a file to an issue (base64-encoded content) |
| List files attached to an issue | |
| Delete a file attachment from an issue | |
Issue Statuses |
| List all issue statuses (workflow states), grouped by phase |
| Create a new issue status — available in every project immediately (tracker-admin) | |
Organizations |
| List all organizations (companies) in the workspace |
| Get details of an organization, including description | |
| Create a new organization (company contact) | |
| Set the description of an organization from Markdown | |
Inbox ( |
| Your notifications, grouped by issue/PR/document |
| 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 | |
| Mark read by object, ids or all; optionally archive | |
| For one object: | |
Activity ( |
| Who changed what, plus comments, for an issue or object |
Planner ( |
| Your to-dos (open/done, due date filter) |
| Create a to-do, optionally attached to an issue | |
| Change title, due date, priority; mark done/reopen | |
| Delete a to-do | |
| Block time for a to-do in your calendar | |
Calendar ( |
| Events and work slots in a date range |
| Manage events in your calendar | |
GitHub ( |
| PRs by project, issue, state |
| State, branches, reviews, review comments, linked issue | |
Generic ( |
| All data classes of the workspace (filter by module, optional counts) |
| Attributes and types of a class | |
| Read documents of any class; secrets are redacted | |
Generic write ( |
| Any class; dry run by default, deletes also need |
Collaboration ( |
| Who follows an issue/document (and gets its notifications) |
| Read-only guest links for issues and documents | |
| Comments on documents | |
Cards ( |
| Card types (MasterTags) and tags |
| Cards by type, parent or title; one card with fields, tags, children, content | |
| With content (Markdown), parent, tags and field values | |
Custom fields ( |
| Fields of issues, a project type, card type or class — or the values on one object |
| string, number, boolean, date, markup, enum (with values) or ref | |
| Set values on an issue, card or document (validated against the type) | |
Drive ( |
| Drives and their folder tree |
| Folders; rename/move files and folders (across drives too) | |
| Base64 or local files under | |
| File history | |
Issue templates ( |
| Templates with their sub-issues |
| Priority, assignee, component, milestone, estimation, labels, sub-issues | |
| New issue plus sub-issues from a template | |
Test management ( |
| Test projects |
| Suites (nested) and cases | |
| Plans from suites and/or cases | |
| Runs with Passed/Failed/Blocked results; results can be assigned | |
| Many cases in one call (e.g. drafted from a spec or an issue); existing names are skipped | |
| Rename/move suites (no cycles), delete with | |
| JUnit XML from CI (Jest, Vitest, pytest, Go, Gradle, Maven, xcpretty …) as a run; missing suites/cases are created, failures keep message and stack trace | |
| Over the latest runs: failing now, flaky (flipped ≥ 2×), blocked, never run, per-suite table | |
| Bug from a failed result: steps + failure in the description, related to the test case, comment on the result | |
Products ( |
| Products and their versions (read-only) |
Labels ( |
| Group issue labels |
Project types ( |
| Project types, their task types and status workflows, and which projects use them |
Workspace ( |
| Your role, members per role, invite defaults, integrations |
| Invite links (personal or with use limit and e-mail mask; nothing is sent), invitation e-mails, roles. | |
Recruiting ( |
| Vacancies with applications per status; archive via |
| Candidates (person + title, e-mail, onsite/remote) | |
| Applications | |
CRM ( |
| Leads |
HR ( |
| Department tree, team leads, members |
| Vacation, sick days, PTO, overtime, remote days | |
Inventory ( |
| Categories, products, variants with SKU (Huly beta module) |
Message templates ( |
| Reusable texts with |
Meetings ( |
| Rooms, meeting minutes, action items and transcripts (read-only) |
QMS ( |
| Controlled documents: version, state, reviewers/approvers, requests, content (read-only) |
| Trainings, questions (answers optional) and trainee results (read-only) | |
Processes ( |
| Process states and transitions; running executions; run a process on a card like Huly's "Run process" menu (processes that ask for input in the app are refused); cancel asks first |
Surveys ( |
| Surveys and aggregated poll answers (read-only) |
Workspaces (one account, several workspaces)
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.
list_workspacesreturns name, slug and id of every available workspace.Every other tool takes a
workspaceargument — the slug, the name or the id (case-insensitive):list_projects(workspace="jokeks2023"),get_issue(workspace="acme", identifier="PROJ-1"),log_time(workspace="jokeks2023", identifier="WEB-12", hours=2).Changes always require
workspace. Every tool that creates, updates, deletes, links, sends, attaches or logs something hasworkspaceas a required argument — the server never falls back to an implicit, default or "last used" workspace for a write.Reads may omit
workspaceonly if exactly one workspace is available. With several, the call fails and lists the options.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 sameworkspaceyou got the id from.Each workspace gets its own lazily opened, cached WebSocket connection with its own workspace token (via
selectWorkspace()), so workspaces never share state.
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.
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.
Configuration
Variable | Required | Purpose |
| one auth option | Account login (needs a password set on your Huly account) |
| one auth option | Account token for SSO accounts (Google/GitHub) — get it with |
| self-hosted only | Account service — login and workspace discovery. Default |
| self-hosted (optional on Cloud) | Front service — document/description content and file uploads. Not involved in login or workspace discovery. Self-hosted: e.g. |
| no | Self-hosted, server next to Huly: connect to the transactor directly instead of the public address the account service returns, e.g. |
| no | Pin the server to one workspace; tools then take no |
| no |
|
| no |
|
| no | Comma-separated toolsets to enable, or |
| no | Only allow changes in these projects, e.g. |
| no | Append every change as JSON line to this file |
| no | Default agent name for |
| no |
|
| no | Directory for local files: |
| no | Docker only: |
| no | HTTP mode: turns on "log in with Huly" (OAuth); at least 32 characters, e.g. |
| with OAuth | The HTTPS address clients reach the server at (issuer and login page), e.g. |
| no | HTTP mode: bearer token every client must send; required before the server's own |
| no |
|
| no | How often subscribed |
Authentication
Create a .env file in the project root (or pass via env in your client config). No workspace is needed in either option.
Option A — Email + password (recommended):
Works if you have a password set on your Huly account (Profile → Security → Change password).
HULY_EMAIL=your@email.com
HULY_PASSWORD=yourpasswordOption B — Token (SSO accounts: Google/GitHub):
npx huly-mcp-selfhost setup # Huly Cloud
npx huly-mcp-selfhost setup --url https://huly.example.com # self-hostedThe 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.
HULY_TOKEN=your-token-hereA 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.
Tokens expire after some time. If you get an auth error, run
npx huly-mcp-selfhost setupagain or switch to email + password.
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.
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.
Self-hosted Huly:
HULY_ACCOUNTS_URL=https://your-huly-instance.com/_accounts # login + workspace discovery
HULY_FRONT_URL=https://your-huly-instance.com # document content + file uploadsCompatible clients
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). To run a local build instead, replace npx + args with node + ["/absolute/path/to/huly-mcp/dist/index.js"].
Self-hosted: add HULY_ACCOUNTS_URL and HULY_FRONT_URL to every env block below.
Claude Desktop
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"huly": {
"command": "npx",
"args": ["-y", "huly-mcp-selfhost"],
"env": {
"HULY_EMAIL": "you@example.com",
"HULY_PASSWORD": "your-password"
}
}
}
}Restart Claude Desktop after saving.
Claude Code (CLI)
claude mcp add huly \
-e HULY_EMAIL=you@example.com \
-e HULY_PASSWORD=your-password \
-- npx -y huly-mcp-selfhostAdd --scope project (writes .mcp.json, shared with the repo — don't commit secrets) or --scope user (all your projects) after add huly. Verify with claude mcp list.
Cursor
Create or edit ~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"huly": {
"command": "npx",
"args": ["-y", "huly-mcp-selfhost"],
"env": {
"HULY_EMAIL": "you@example.com",
"HULY_PASSWORD": "your-password"
}
}
}
}The tools appear in the Agent panel under MCP.
Windsurf
Create or edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"huly": {
"command": "npx",
"args": ["-y", "huly-mcp-selfhost"],
"env": {
"HULY_EMAIL": "you@example.com",
"HULY_PASSWORD": "your-password"
}
}
}
}Refresh the MCP servers in the Cascade panel.
VS Code — Cline
Cline → MCP Servers → Installed → Configure MCP Servers (opens cline_mcp_settings.json):
{
"mcpServers": {
"huly": {
"command": "npx",
"args": ["-y", "huly-mcp-selfhost"],
"env": {
"HULY_EMAIL": "you@example.com",
"HULY_PASSWORD": "your-password"
},
"disabled": false
}
}
}VS Code / JetBrains — Continue
Add to ~/.continue/config.yaml (MCP tools are available in Agent mode):
mcpServers:
- name: huly
command: npx
args: ["-y", "huly-mcp-selfhost"]
env:
HULY_EMAIL: you@example.com
HULY_PASSWORD: your-passwordZed
Add to ~/.config/zed/settings.json:
{
"context_servers": {
"huly": {
"source": "custom",
"command": "npx",
"args": ["-y", "huly-mcp-selfhost"],
"env": {
"HULY_EMAIL": "you@example.com",
"HULY_PASSWORD": "your-password"
}
}
}
}OpenAI Codex CLI
Add to ~/.codex/config.toml:
[mcp_servers.huly]
command = "npx"
args = ["-y", "huly-mcp-selfhost"]
env = { HULY_EMAIL = "you@example.com", HULY_PASSWORD = "your-password" }or: codex mcp add huly --env HULY_EMAIL=you@example.com --env HULY_PASSWORD=your-password -- npx -y huly-mcp-selfhost
Any other MCP-compatible client
The server uses standard stdio transport:
command:
npxwith args["-y", "huly-mcp-selfhost"], ornodewith["/absolute/path/to/huly-mcp/dist/index.js"]env:
HULY_EMAIL+HULY_PASSWORD(orHULY_TOKEN); self-hosted alsoHULY_ACCOUNTS_URL+HULY_FRONT_URL— see Configuration
For network access (HTTP/SSE) use the Docker image.
Running the server
npx (recommended)
Every client example uses "command": "npx", "args": ["-y", "huly-mcp-selfhost"]. Pin a version (huly-mcp-selfhost@3.5.1) if you want updates only when you choose.
From source
git clone https://github.com/JoKeks2023/huly-mcp.git
cd huly-mcp
npm ci && npm run buildThen use "command": "node", "args": ["/absolute/path/to/huly-mcp/dist/index.js"].
Docker
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:
docker pull jokeks2023/huly-mcp:latest # latest release; also :3, :3.1, :3.1.0
# also mirrored at ghcr.io/jokeks2023/huly-mcp:latest
# :edge = latest build from mainOr with Compose — copy .env.example to .env, fill in your credentials (no workspace needed), then:
docker compose up -dThe container wraps the server with 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 / docker-compose.yml.
Team server over HTTP
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.
npx huly-mcp-selfhost http --host 0.0.0.0 --port 8000Everyone with their own Huly account. A client sends its own login as headers; the session then acts as that person:
claude mcp add --transport http huly https://huly-mcp.example.com/mcp \
--header "X-Huly-Token: <your token>" # or X-Huly-Email + X-Huly-Password
# optional: --header "X-Huly-Workspace: acme" # pin one workspace (fewer tokens)Log in with Huly (OAuth). Set MCP_OAUTH_SECRET (openssl rand -hex 32) and MCP_PUBLIC_URL (the HTTPS address clients reach, e.g. https://huly-mcp.example.com). Then people simply add https://huly-mcp.example.com/mcp in their AI app — Claude Code (claude mcp add --transport http huly …), Claude's custom connectors and other OAuth-capable MCP clients — and log in in the browser with their own Huly account: e-mail + password, or a one-time code by e-mail for Google/GitHub accounts. One server, as many people as you like, nobody handles tokens.
Stateless: registrations, codes and tokens are sealed with AES-256-GCM under
MCP_OAUTH_SECRET— no database, logins survive restarts. Changing the secret logs everyone out.The Huly password goes only to your Huly server; the server keeps just the resulting Huly token, inside the sealed tokens. Access tokens last 1 hour, refresh tokens 30 days and work once (rotation). Login attempts are throttled per address.
The protocol parts (client registration, PKCE, token endpoint, metadata) are the MCP SDK's own; this server adds the login page and the tokens.
X-Huly-Workspacestill pins a workspace. In OAuth mode/mcpneeds the OAuth token;MCP_AUTH_TOKENand theX-Huly-*login headers are for the other mode.
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.
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.
Example prompts
Workspaces:
"Which Huly workspaces do I have?"
"List the projects in my Acme workspace"
"In the jokeks2023 workspace, log 2 hours on WEB-12"
Projects & issues:
"Create a new project called 'Mobile App' with identifier MOBILE"
"List all in-progress issues in the PROJ project"
"Create a high-priority issue in PROJ titled 'Fix login timeout'"
"Update PROJ-42 status to Done, assign it to Sarah, and move it to the Auth component"
"Search for issues related to authentication"
"Add a comment to PROJ-15 saying the fix is deployed"
"List all comments on PROJ-42 to see the discussion"
Milestones & components:
"Create a milestone 'v2.0 Launch' in PROJ with target date 2026-06-01"
"List milestones for the PROJ project"
"Create a component called 'Auth' in PROJ"
"List all components in PROJ"
"How far along is milestone v2.0 Launch in PROJ?"
"Move the v2.0 Launch milestone to 2026-07-15 and set it to In Progress"
"Delete milestone 'Beta' in PROJ and move its issues to 'v2.0 Launch'"
Planning & bulk work:
"Which issues in milestone v2.0 Launch carry the label 'bug' and are still unassigned?"
"Set PROJ-12, PROJ-13 and PROJ-20 to In Progress and put them into milestone v2.0 Launch"
"Show me the sub-issue tree of PROJ-1 and how far along it is"
"How many hours did we log on PROJ in October, per person?"
"Move PROJ-42 to the OPS project"
Inbox, planner, calendar:
"What's new in my inbox? Mark everything about PROJ-12 as read"
"Create a to-do 'Review PR' on PROJ-7 due Friday and block 45 minutes tomorrow at 9"
"What's on my calendar this week?"
"Show the history of PROJ-12 — who moved it to Done?"
"Which pull requests are waiting for review in PROJ?"
Labels & relations:
"Add the label 'bug' to PROJ-42"
"Create a label called 'backend' with color #3b82f6"
"Mark PROJ-55 as blocked by PROJ-12"
"Set PROJ-42 as a subtask of PROJ-5"
Time tracking:
"Log 2.5 hours on PROJ-42 for the database refactor"
Documents:
"List all documents in the Engineering teamspace"
"Create a document called 'API Design' in the Engineering teamspace"
"Update the API Design document with this Markdown: ..."
"Add a Mermaid architecture diagram to the EP1 document"
"Link document abc123 to issue PROJ-42"
"Delete the second comment on PROJ-15"
Document content
Reading: get_document
get_document always returns full metadata (title, teamspace, comments, snapshots). To also fetch and display the text content, set the optional HULY_FRONT_URL env var:
"env": {
"HULY_EMAIL": "...",
"HULY_PASSWORD": "...",
"HULY_FRONT_URL": "https://front.huly.app"
}HULY_FRONT_URL only serves document/description content and file uploads — each request uses the token of the workspace named in the tool call. It plays no part in login or workspace discovery (that is HULY_ACCOUNTS_URL).
For self-hosted Huly, set HULY_FRONT_URL to your own front service URL (e.g. http://localhost:8083).
Writing: update_document
update_document accepts a documentId and a markdown string and writes rich structured content directly to the document — no manual editing required.
Self-hosted note: Document content (and, as of this fork, issue descriptions — see below) is stored as a
MarkupBlobRefblob. Huly Cloud uploads these through a dedicated "datalake" microservice at a fixed URL;huly-selfhost(v0.7.x) does not run that service — blob storage goes throughfront's own, older/filesendpoint instead. IfHULY_FRONT_URLis set, this fork uploads through that self-hosted contract automatically; if it's unset, it falls back to Huly Cloud's datalake (the original, upstream behavior). No separate flag needed —HULY_FRONT_URLdoubles as the self-host/cloud switch for both reading and writing.
Supported Markdown:
Element | Syntax |
Headings |
|
Bold / inline code |
|
Paragraphs | plain text |
Bullet lists |
|
Pipe tables |
|
Code blocks |
|
Mermaid diagrams |
|
Example:
update_document({
documentId: "abc123",
markdown: `# Service Flow\n\n` +
`## Architecture\n\n` +
"```mermaid\n" +
"flowchart TD\n" +
" A([User]) --> B[Browse Catalogue]\n" +
" B --> C[Pay via Razorpay]\n" +
" C --> D[Order Confirmed]\n" +
"```\n\n" +
"## Business Rules\n\n" +
"- Payment required before confirmation\n" +
"- All orders synced to HIS\n"
})The Mermaid block renders as a live interactive diagram in Huly's document editor — not as a code block.
Bulk CSV Import
Import many issues at once from a CSV file — useful for migrating from other tools:
npm run build
node scripts/import-csv.js tasks.csv PROJ --workspace=myteamThe target workspace is required (--workspace=<slug>, or HULY_WORKSPACE as a fallback), since the script writes data. Credentials come from the environment as for the server.
CSV format:
title,priority,status,dueDate
Fix login bug,High,In Progress,2025-04-01
Add dark mode,Medium,,
Improve performance,Urgent,,2025-05-01Required column: title. Optional: priority (Urgent/High/Medium/Low), status (must match a status name in the project), dueDate (YYYY-MM-DD).
Architecture
HULY_EMAIL + HULY_PASSWORD (or HULY_TOKEN)
↓
account login (once) account-level client: getUserWorkspaces(), selectWorkspace()
↓
getUserWorkspaces() → workspace discovery (cached)
↓
WorkspaceConnectionManager
├── workspace A: selectWorkspace(A) → endpoint + token → WebSocket (cached)
├── workspace B: selectWorkspace(B) → endpoint + token → WebSocket (cached)
└── … workspace-level client (workspace token): getWorkspaceMembers()
↓
MCP tools (each call names its workspace)One login, many workspaces — the account session is shared; each workspace gets its own long-lived connection via
@hcengineering/server-client(model load takes 1–3 s, so connections are reused, not opened per call)Lazy — nothing connects until the first tool call, and a workspace connects only when first used, so auth errors surface clearly in the client
No current workspace — there is no global or "last used" workspace; see Workspaces
Stdio transport — standard MCP transport; the Docker image adds HTTP/SSE via
mcp-proxy
See src/connection.ts.
Development and CI
npm ci && npm run build && npm testnpm run build type-checks (tsc --noEmit) and bundles src/ with all dependencies into one readable file, dist/index.js (esbuild, not minified), plus dist/guides/. The published package therefore has no runtime dependencies; everything in package.json is a dev dependency. Tests run on the TypeScript sources (tsx).
GitHub Actions check every pull request:
Workflow | What it checks |
| build and tests on Node 20/22/24 (Linux), macOS and Windows; the built server answers |
| CodeQL security analysis (also weekly) |
| broken links in Markdown and the site (on PRs that touch them, and weekly → issue) |
| Dependabot patch/minor updates merge by themselves once checks are green; majors and Huly packages wait for review |
| nightly live smoke test against a sandbox workspace; weekly: the latest |
| on a |
Security reports: see SECURITY.md.
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.
Releasing:
Move the
Unreleasedentries inCHANGELOG.mdunder### X.Y.Z — date.Bump the version in
package.json,server.json,plugin/.claude-plugin/plugin.json,plugin/.mcp.json(exact npx version) andsrc/server.ts. The tests check that they agree.Merge, then tag
vX.Y.Zonmain. The rest runs by itself.
Environments and secrets:
Environment
release(tagsv*only): used byrelease.yml. npm Trusted Publishing names this environment.Environment
sandbox: used by the nightly live jobs.
Secrets:
PERSONAL_DATA_PATTERNS: private terms that must never appear in the repo, one regex per line.NPM_TOKEN: fallback only, until Trusted Publishing is set up on npmjs.com.In the environment
sandbox:HULY_SMOKE_WORKSPACE,HULY_SMOKE_PROJECT,HULY_SMOKE_EMAIL+HULY_SMOKE_PASSWORD(orHULY_SMOKE_TOKEN),HULY_SMOKE_ACCOUNTS_URL,HULY_SMOKE_FRONT_URL: a throwaway workspace for the nightly live test. Without them the live jobs skip.
Changelog
See CHANGELOG.md.
Credits
Started as a fork of varaprasadreddy9676/huly-mcp (npm huly-mcp-sdk) by SaiVaraprasad Medapati and grown from its 33 tools to 227, with self-hosted support, toolsets, agent workflow and the Claude Code plugin. Published separately as huly-mcp-selfhost. Not affiliated with Huly Labs.
Links
Source and issues: https://github.com/JoKeks2023/huly-mcp
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-selfhostSecurity: SECURITY.md
License
Available Tools
99 toolsadd_blocked_byC
Mark an issue as blocked by another issue
Inputs: blockedBy (required), workspace (required), identifier (required).
add_commentC
Add a comment to an issue
Inputs: message (required), workspace (required), identifier (required).
add_contact_channelC
Add email/phone/… to a person
Inputs: value (required), person (required), provider (required), workspace (required).
add_labelC
Add label to issue (auto-creates label)
Inputs: labelName (required), workspace (required), identifier (required).
add_reactionC
React to a message/comment with an emoji
Inputs: emoji (required), messageId (required), workspace (required).
add_relationB
Mark two issues as related to each other (bidirectional)
Inputs: relatedTo (required), workspace (required), identifier (required).
attach_fileB
Attach a file to an issue (base64-encoded content)
Inputs: filename (required), workspace (required), identifier (required), contentBase64 (required), +1 more.
bulk_update_issuesBDestructive
Apply one change to many issues; validates all first
Inputs: workspace (required), identifiers (required), dueDate, assignee, +4 more.
changes_sinceCRead-only
Issues/PRs changed since a time: fields, comments, who
Inputs: since (required), limit, workspace, projectIdentifiers.
check_setupBRead-only
Diagnose the setup: version and updates, login, workspaces, front URL, settings (no secrets)
Inputs: workspace, skipVersionCheck.
claim_issueB
Lease an issue so parallel agents skip it
Inputs: workspace (required), identifier (required), agent, force, +1 more.
create_channelD
Create a new channel
Inputs: name (required), workspace (required), topic, isPrivate.
create_componentC
Create a new component in a project
Inputs: label (required), workspace (required), projectIdentifier (required), lead, +1 more.
create_documentC
Create a new document in a teamspace
Inputs: title (required), workspace (required), teamspaceId (required), parentId.
create_issueC
Create a new issue in a project
Inputs: title (required), workspace (required), projectIdentifier (required), dueDate, +6 more.
create_issue_treeB
Plan → epic + sub-issues with blockers; skips duplicates; dry run first
Inputs: children (required), workspace (required), projectIdentifier (required), epic, +5 more.
create_labelC
Create a new label with an optional hex color
Inputs: title (required), workspace (required), color.
create_milestoneC
Create a new milestone in a project with a target date
Inputs: label (required), workspace (required), targetDate (required), projectIdentifier (required), +1 more.
create_organizationC
Create a new organization (company contact)
Inputs: name (required), workspace (required), city.
create_personC
Create a contact person
Inputs: firstName (required), workspace (required), city, channels, +1 more.
create_teamspaceC
Create a document teamspace
Inputs: name (required), workspace (required), isPrivate, description.
create_todoC
Create a to-do, optionally on an issue
Inputs: title (required), workspace (required), issue, dueDate, +2 more.
delete_attachmentCDestructive
Delete a file attachment from an issue
Inputs: workspace (required), identifier (required), attachmentId (required).
delete_commentCDestructive
Delete a comment by id
Inputs: commentId (required), workspace (required), identifier (required).
delete_documentADestructive
Permanently delete a document by its ID
Inputs: workspace (required), documentId (required).
delete_issueBDestructive
Permanently delete an issue by identifier (e.g. "PROJ-123")
Inputs: workspace (required), identifier (required).
delete_messageCDestructive
Delete a message or thread reply
Inputs: messageId (required), workspace (required).
delete_todoCDestructive
Delete a to-do
Inputs: todoId (required), workspace (required).
describe_classCRead-only
Attributes and types of a class
Inputs: className (required), workspace.
find_project_for_repoCRead-only
Huly workspace + project linked to a GitHub repo
Inputs: repository (required), workspace.
finish_workC
Hand back: summary comment, link PR, status to review
Inputs: summary (required), workspace (required), identifier (required), statusName, +1 more.
get_activityCRead-only
Change history and comments of an issue or object
Inputs: object (required), limit, workspace.
get_documentCRead-only
Document metadata and content
Inputs: documentId (required), workspace.
get_issueBRead-only
Get full details of an issue by identifier (e.g. "PROJ-123")
Inputs: identifier (required), workspace.
get_issue_contextCRead-only
Issue with description, sub-issues, blockers, PRs, comments, branch name
Inputs: identifier (required), workspace, commentLimit.
get_milestoneDRead-only
Milestone with progress and open issues
Inputs: label (required), projectIdentifier (required), workspace.
get_organizationBRead-only
Get details of an organization, including description
Inputs: organizationId (required), workspace.
get_personDRead-only
Person details, channels, organizations
Inputs: person (required), workspace.
get_projectBRead-only
Get a project by its identifier (e.g. "PROJ")
Inputs: identifier (required), workspace.
issues_from_documentB
Spec → epic + sub-issues from a document's open checklist items (else its sections); links the doc. Dry run first
Inputs: document (required), workspace (required), projectIdentifier (required), dryRun, +5 more.
issues_from_meetingB
Meeting notes → issues: action items with @assignee and due date; links the doc. Dry run first
Inputs: document (required), workspace (required), projectIdentifier (required), dryRun, +3 more.
link_documentC
Link a document to an issue (Relations panel)
Inputs: workspace (required), documentId (required), identifier (required).
list_attachmentsCRead-only
List files attached to an issue
Inputs: identifier (required), workspace.
list_channelsCRead-only
List all channels in the workspace
Inputs: workspace, includeArchived.
list_classesBRead-only
Huly data classes (for modules without dedicated tools)
Inputs: module, workspace, withCounts.
list_commentsCRead-only
List comments of an issue (with ids)
Inputs: identifier (required), full, limit, workspace.
list_componentsCRead-only
List components (sub-areas) in a project
Inputs: projectIdentifier (required), workspace.
list_documentsCRead-only
List documents in a teamspace
Inputs: teamspaceId (required), workspace.
list_issuesCRead-only
List issues of a project; filters: status, priority, milestone, component, label, assignee, parent
Inputs: projectIdentifier (required), due, limit, title, +9 more.
list_issue_statusesBRead-only
List all issue statuses (workflow states), grouped by phase
Inputs: workspace.
list_labelsBRead-only
List all labels in the workspace
Inputs: workspace, projectIdentifier.
list_membersCRead-only
List all members in the workspace
Inputs: workspace.
list_messagesCRead-only
List messages in a channel or direct message
Inputs: spaceId (required), limit, workspace.
list_milestonesCRead-only
List milestones for a project
Inputs: projectIdentifier (required), workspace.
list_notificationsCRead-only
Your inbox notifications, grouped by issue/PR/document
Inputs: ids, limit, workspace, unreadOnly.
list_organizationsBRead-only
List all organizations (companies) in the workspace
Inputs: workspace.
list_personsCRead-only
Contact persons with their channels
Inputs: limit, query, workspace, employeesOnly.
list_projectsCRead-only
List all projects in a Huly workspace
Inputs: workspace.
list_sub_issuesCRead-only
Sub-issue tree of an issue with progress
Inputs: identifier (required), depth, workspace.
list_teamspacesCRead-only
List all document teamspaces in the workspace
Inputs: workspace.
list_threadCRead-only
Message with its thread replies
Inputs: messageId (required), limit, workspace.
list_time_reportsBRead-only
Logged time for an issue or project, totals per person; person/date filters
Inputs: to, from, limit, member, +3 more.
list_todosDRead-only
Your planner to-dos
Inputs: limit, status, dueBefore, workspace.
list_workspacesARead-only
List accessible workspaces (name, slug, id)
Inputs: no named parameters.
log_timeC
Log hours spent on an issue
Inputs: hours (required), workspace (required), identifier (required), description.
manage_notificationsC
Inbox for one object: pin, hide, mark unread, unarchive, follow/unfollow (and the undo of each)
Inputs: action (required), object (required), workspace (required).
mark_notifications_readA
Mark notifications read (by object, ids or all); optionally archive
Inputs: workspace (required), all, object, archive, +1 more.
move_issueADestructive
Move issue (incl. sub-issues, comments, files, time) to another project; gets a new id, component/milestone cleared
Inputs: workspace (required), identifier (required), targetProjectIdentifier (required), statusName.
my_dayBRead-only
Today at a glance: calendar, to-dos, my issues, reviews, unread inbox
Inputs: date, limit, workspace.
pin_messageB
Pin or unpin a message
Inputs: messageId (required), workspace (required), pinned.
project_reportCRead-only
Weekly report: done, new, blocked, overdue, PRs, milestones, time
Inputs: projectIdentifier (required), since, workspace.
query_documentsCRead-only
Read documents of any class (secrets redacted)
Inputs: className (required), limit, query, fields, +1 more.
release_issueC
Release an agent claim
Inputs: workspace (required), identifier (required), agent.
release_notesBRead-only
Release notes from a milestone: features, fixes, PRs, still open
Inputs: milestoneLabel (required), projectIdentifier (required), workspace.
remove_blocked_byCDestructive
Remove a "blocked by" link from an issue
Inputs: blockedBy (required), workspace (required), identifier (required).
remove_contact_channelCDestructive
Remove email/phone/… from a person
Inputs: value (required), person (required), provider (required), workspace (required).
remove_labelBDestructive
Remove a label from an issue
Inputs: labelName (required), workspace (required), identifier (required).
remove_reactionBDestructive
Remove your emoji reaction
Inputs: emoji (required), messageId (required), workspace (required).
remove_relationBDestructive
Remove the "related" link between two issues
Inputs: relatedTo (required), workspace (required), identifier (required).
reply_to_messageC
Reply in the thread of a message or comment
Inputs: message (required), messageId (required), workspace (required).
schedule_todoC
Block time for a to-do in your calendar
Inputs: start (required), todoId (required), workspace (required), durationMinutes.
searchCRead-only
Fulltext search across everything (issues, docs, messages, cards, files …)
Inputs: query (required), kinds, limit, workspace.
search_issuesCRead-only
Full-text search across all issues
Inputs: query (required), limit, workspace.
send_messageC
Send a message to a channel or direct message
Inputs: message (required), spaceId (required), workspace (required).
set_parentC
Set or clear the parent (epic) of an issue
Inputs: workspace (required), identifier (required), parentIdentifier.
standupCRead-only
Standup: what I did since the last working day, today, blockers
Inputs: since, workspace.
start_direct_messageB
Start or find a 1:1 DM with a person
Inputs: member (required), workspace (required).
start_workC
Pick up issue: In Progress, assign me, return context
Inputs: workspace (required), identifier (required), claimAs, assignToMe, +1 more.
triage_inboxBRead-only
Unread items with what changed since last read: new comments, fields, status
Inputs: limit, workspace.
undo_changesADestructive
Undo your last changes made through this server: created → removed, changed → old values, deleted → restored. Dry run first
Inputs: workspace (required), count, force, dryRun.
update_commentC
Edit a comment by id
Inputs: message (required), commentId (required), workspace (required), identifier (required).
update_componentC
Update a component (name, description, lead)
Inputs: label (required), workspace (required), projectIdentifier (required), lead, +2 more.
update_documentA
Replace content (Markdown), rename or move a document
Inputs: workspace (required), documentId (required), title, markdown, +2 more.
update_issueC
Update issue fields
Inputs: workspace (required), identifier (required), title, dueDate, +6 more.
update_messageC
Edit a message or thread reply
Inputs: message (required), messageId (required), workspace (required).
update_milestoneC
Update a milestone (name, target date, status, description)
Inputs: label (required), workspace (required), projectIdentifier (required), status, +3 more.
update_organizationC
Set the description of an organization from Markdown
Inputs: workspace (required), description (required), organizationId (required).
update_personC
Update a contact person
Inputs: person (required), workspace (required), city, lastName, +1 more.
update_todoC
Update a to-do or mark it done
Inputs: todoId (required), workspace (required), done, title, +3 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 99 tools
Most tools target a distinct resource+action, but several clusters blur together: get_issue vs get_issue_context vs get_activity vs list_sub_issues, search vs search_issues vs query_documents, and the notification group (list_notifications, triage_inbox, manage_notifications, mark_notifications_read). Issue-creation also overlaps across create_issue, create_issue_tree, issues_from_document and issues_from_meeting, and the agent-workflow helpers (claim_issue/release_issue vs start_work/finish_work) describe closely related states. Descriptions do help, but an agent must read carefully to pick correctly.
Names are uniformly snake_case with a strong verb_noun bias (create_issue, update_milestone, remove_reaction, list_attachments), which is highly predictable. Deviations are limited to a handful of noun-first or verb-less labels like my_day, standup, project_report, release_notes and changes_since, which are readable but break the pattern.
99 tools is far beyond what an agent can comfortably select from, even though Huly genuinely spans issues, documents, chat, contacts and notifications. Several tools are near-duplicates or convenience wrappers (my_day, standup, triage_inbox, check_setup) that could be folded into broader calls. The surface would benefit from consolidation into per-domain entry points.
Coverage is unusually deep: full CRUD for issues, documents, todos, comments, messages, attachments and relations, plus reporting, time tracking, workflow helpers and generic class queries. Gaps are mostly delete/create operations for secondary entities (no delete for projects, milestones, components, persons, organizations, labels or channels, and no create_project), but agents can work around these.
Maintenance
Related MCP Connectors
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Work management where AI agents are first-class members: tasks, projects, memory over hosted MCP
AI-native git hosting — repos, PRs, issues, CI gates, and AI code review over MCP (60 tools).
Task & board management for AI agents + humans. Kanban, comments, digests via MCP.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for Huly (task tracker) integration61,022 npm64MIT
- AlicenseNot gradedqualityCmaintenanceComplete MCP server for Huly project management with 209 tools across 23 categories — issues, projects, tasks, comments, documents, cards, channels, calendar, time tracking, test management, processes, custom fields, attachments, leads and more. Includes custom task type support (Ticket, Bug, Feature) with project-scoped status workflows and read-side Process plugin tools.24 npmMIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI assistants to interact with Huly's project and document management platform, providing search and write actions for issues, milestones, and more.7 npmMIT
- AlicenseBqualityAmaintenanceSelf-hosted issue tracker built for agent-driven development. One binary, SQLite storage, MCP-native, with a web UI, REST API, and CLI for the humans.2789Apache 2.0