huly-mcp-selfhost
- Huly for AI agents.
- Self-hosted + Huly Cloud.
- 2.9× fewer tokens per answer.
- One server for the team — log in with Huly.
- 227 tools · undo · no telemetry · 4 MB.
Pick your client. Paste. Done.
Account credentials only. The server finds your workspaces itself. Claude Code: install the plugin instead — /plugin marketplace add JoKeks2023/huly-mcp, then /huly:setup in your repo.
claude mcp add huly \
-e HULY_EMAIL=you@example.com \
-e HULY_PASSWORD=your-password \
-- npx -y huly-mcp-selfhost
Add --scope user (all projects) or --scope project (.mcp.json — don’t commit secrets) after “add huly”. Check with: claude mcp list
SSO account without a password? Use HULY_TOKEN instead — see Authentication. More clients (Windsurf, Cline, Continue) in the README. For a whole team: the team server.
Built for agents. Measured, not claimed.
Native Huly SDK over WebSocket — not screen scraping, not a REST shim. Every answer is shaped for a model: open items by default, empty fields left out, one call instead of four.
Same self-hosted Huly, same questions, the best parameters on both sides, measured 2026-11-11. All numbers.
- Agent workflows
my_day,standup,project_report,release_notesandget_issue_contextin one call each;start_work→finish_work; plans, specs and meeting notes → epics and issues; claims for parallel agents;huly-mcp watchhands Huly issues to Claude.- Undo
undo_changesreverses your last changes through the server — for every write tool. Dry run first; skips what someone else changed since.- Claude Code plugin
/huly:setupasks once per repo how Huly is used there and writes the rules; a skill that picks the cheapest call, hooks,/huly:*commands. Guides and asetupprompt for every other MCP client.- Team server
- One container, everyone logs in with their own Huly account in the browser (OAuth). Persistent sessions, ~0.2 s per call.
- Command line
huly-mcp <tool> --param valuefor scripts and CI, generated from the same schemas; completion for bash and zsh.- Safe by default
- Every change names its workspace; risky tools ask first; writes can be limited to projects; audit log; unknown parameters are rejected instead of ignored.
- No telemetry
- It talks to your Huly server and nothing else. One self-contained package, ~4 MB — no 180 dependencies on first start.
One login. Every workspace.
The server discovers what your account can access and keeps a separate connection per workspace. It never guesses which one you mean.
- One account login — email + password or token, once per process.
- Discovery via
getUserWorkspaces();list_workspacesshows name, slug and id. - One cached connection per workspace, opened on first use via
selectWorkspace()with its own workspace token. - No current, default or last-used workspace. Every call names its target.
- Writes require
workspace— enforced by the tool schema, even with a single workspace. - Reads may omit it only when exactly one workspace is available. IDs like
PROJ-1are only unique within their workspace.
› list_workspaces()
- **Acme Team** — slug: `acmeteam` — id: `3f2b9c1e-…`
- **Personal** — slug: `personal` — id: `8a41d7e0-…`
› list_projects(workspace="acmeteam")
## Projects (2) …
› list_projects()
Multiple workspaces available — pass 'workspace' explicitly.
› log_time(identifier="WEB-12", hours=2)
Input validation error: workspace — Required
Every tool, by toolset.
Only the default toolsets are loaded unless you choose more (HULY_TOOLSETS) — or let the agent load them on demand.
Core default
Agent workflow default
Tracker default
Tracker admin
Documents default
Chat default
Contacts default
Inbox default
Activity default
Planner default
Calendar
GitHub
Any Huly class default
Any class — writes
Collaboration
Cards
Custom fields
Drive
Templates
Test management
Products
Members & invites
Recruiting
CRM
HR
Inventory
Meetings
Quality documents
Processes
Surveys
workspace requiredreads: workspace optional when only one is availableA thin, stateful bridge.
No database, no cache service, no extra infrastructure. All state is in process memory: account sessions, the discovered workspaces, one connection per workspace in use and the undo history. OAuth tokens are sealed, so nothing needs storing.
Calls tools over stdio, or over HTTP to the team server — each session with its own Huly login (OAuth or headers).
227 handlers in toolsets. Each resolves its own connection from its workspace argument; inputs are validated against zod schemas first; writes are recorded for undo_changes.
login / getLoginInfoByToken, then getUserWorkspaces() and selectWorkspace(). Never holds a workspace token.
Caches the session, the workspace list and one connection per workspace id. Failed attempts are not cached; shutdown closes everything.
TxOperations for all reads and writes, plus a workspace-scoped account client for getWorkspaceMembers().
Opened with @hcengineering/server-client; loads the workspace model once, then stays open.
Markup blobs (document bodies, descriptions) and attachments — Bearer-authenticated, per workspace.
Built for huly-selfhost. Works on Huly Cloud.
Huly Cloud stores document content in its datalake service, which self-hosted instances don’t run. On a self-hosted instance the server reads and writes it through the front service’s own /files endpoint — and can connect to the transactor internally when it runs next to Huly.
HULY_ACCOUNTS_URL
Account service: login, workspace discovery, selectWorkspace(), members. Defaults to https://account.huly.app. Self-hosted: e.g. https://your-huly-instance.com/_accounts.
HULY_FRONT_URL
Front service: reads document and description content and — when set — handles uploads via /files. Not involved in login or discovery. Self-hosted: e.g. https://your-huly-instance.com.
| Blob operation | HULY_FRONT_URL set | HULY_FRONT_URL unset (Cloud) |
|---|---|---|
| Read content | GET {front}/files?file=…&workspace=… | not fetched — blob ref shown |
| Upload | POST {front}/files | POST dl-eu.huly.app/upload/form-data/{workspace} |
| Delete | DELETE {front}/files?file=… | DELETE dl-eu.huly.app/blob/{workspace}/{id} |
| Auth | Authorization: Bearer <workspace token> — of the workspace named in the call | |
Note: HULY_FRONT_URL doubles as the self-hosted switch for uploads. On a self-hosted instance, always set it.
One server. Everyone logs in with Huly.
Run the HTTP server once; people add its URL in Claude Code, Claude's custom connectors or another MCP client and log in in the browser with their own Huly account. Each session acts as that person.
- Password or one-time code — Google/GitHub accounts get a code by e-mail.
- Nothing to store — registrations, codes and tokens are sealed with AES-256-GCM under one secret; logins survive restarts.
- The password is never kept — only the Huly token from the login, inside the sealed tokens. Access tokens last an hour, refresh tokens rotate.
- Protocol from the MCP SDK — client registration, PKCE, token endpoint, metadata.
- Without OAuth: per-user
X-Huly-*headers, or one shared account only behindMCP_AUTH_TOKEN.
docker run -d -p 8000:8000 \
-e MCP_TRANSPORT=http \
-e MCP_OAUTH_SECRET="$(openssl rand -hex 32)" \
-e MCP_PUBLIC_URL=https://huly-mcp.example.com \
-e HULY_ACCOUNTS_URL=https://huly.example.com/_accounts \
-e HULY_FRONT_URL=https://huly.example.com \
jokeks2023/huly-mcp
claude mcp add --transport http huly \
https://huly-mcp.example.com/mcp
# → browser: "Log in with Huly"
Keep the secret fixed (env file) and put the server behind HTTPS at MCP_PUBLIC_URL. Changing the secret logs everyone out.
Your data stays between you and your Huly.
- No telemetry
- No analytics, no usage tracking, nothing to opt out of. The only other request — the npm version check — runs when you call
check_setup. - Tokens in headers
- Workspace tokens travel only as
Authorizationheaders, never in URLs or tool results — covered by regression tests; tokens in logs are masked. - Guard rails
- Writes always name their workspace;
HULY_WRITE_PROJECTSlimits where; risky tools ask first (HULY_CONFIRM);HULY_AUDIT_LOGrecords every change;undo_changesreverses them. - Supply chain
- npm Trusted Publishing with provenance; Docker images with SBOM and build provenance; one bundled, readable file — no runtime dependencies to audit.
Five ways to run it.
npm
Launched by your MCP client over stdio. Node.js ≥ 20, ~4 MB.
npx -y huly-mcp-selfhostClaude Desktop extension
One file, double-click, enter your Huly login. Claude Desktop brings Node.js; secrets go to the keychain.
Download .mcpb ↓Claude Code plugin
Server, skill, hooks and /huly:* commands.
/plugin marketplace add JoKeks2023/huly-mcp
/plugin install huly@huly-mcpDocker
The team server above, or classic mode via mcp-proxy (/mcp, /sse). amd64 + arm64.
docker run -d --name huly-mcp -p 127.0.0.1:8000:8000 \
--env-file .env jokeks2023/huly-mcp:latestCommand line
Every tool from the terminal, for scripts and CI.
npm i -g huly-mcp-selfhost
huly-mcp help list_issues