npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bgx4k3p/huly-mcp-server

v2.2.3

Published

MCP server for Huly issue tracking with stdio and Streamable HTTP transports

Downloads

903

Readme

Huly MCP Server

npm License: MIT Node.js MCP Huly SDK Docker

MCP server providing full coverage of the Huly SDK — issues, projects, workspaces, members, and account management. Two transports: stdio for local tools and Streamable HTTP for remote clients. Tested against self-hosted Huly. May also work with Huly Cloud (not yet tested).

Why This Exists

Huly has no public API. The only programmatic access is through their JavaScript SDK, which connects via WebSocket. This server wraps that SDK and exposes MCP tools over both stdio and Streamable HTTP transports — compatible with Claude Code, VS Code, n8n, and any MCP client.

Install

From npm

npm install @bgx4k3p/huly-mcp-server

Or run directly with npx:

npx @bgx4k3p/huly-mcp-server

From source

git clone https://github.com/bgx4k3p/huly-mcp-server.git
cd huly-mcp-server
npm install

Publishing

The Huly SDK has workspace: protocol references in transitive dependencies on the npm registry. The custom pack script bundles only the needed SDK packages and prunes UI bloat (32MB to 4MB):

npm run pack
npm publish bgx4k3p-huly-mcp-server-<version>.tgz --access public

Quick Start

Authentication

You can authenticate with either email/password or a token.

Email and Password

export HULY_URL=https://your-huly-instance.com
export [email protected]
export HULY_PASSWORD=your-password
export HULY_WORKSPACE=your-workspace

Token (recommended)

Get a token from your Huly credentials — no env vars needed beforehand:

node src/index.mjs --get-token -e [email protected] -p your-password -u https://your-huly-instance.com

Then use it:

export HULY_URL=https://your-huly-instance.com
export HULY_TOKEN=<paste-token-from-above>
export HULY_WORKSPACE=your-workspace

The token does not expire. You can store it in a secrets manager and stop exposing your password in environment variables.


Integrations

Claude Code (stdio)

After cloning and running npm install, register the server:

claude mcp add huly \
  -e HULY_URL=https://your-huly-instance.com \
  -e HULY_TOKEN=your-token \
  -e HULY_WORKSPACE=your-workspace \
  -- node /absolute/path/to/huly-mcp-server/src/index.mjs

Or add to your .mcp.json manually (token auth — recommended):

{
  "mcpServers": {
    "huly": {
      "command": "node",
      "args": ["/path/to/huly-mcp-server/src/index.mjs"],
      "env": {
        "HULY_URL": "https://your-huly-instance.com",
        "HULY_TOKEN": "${HULY_TOKEN}",
        "HULY_WORKSPACE": "${HULY_WORKSPACE}"
      }
    }
  }
}

Or with email/password:

{
  "mcpServers": {
    "huly": {
      "command": "node",
      "args": ["/path/to/huly-mcp-server/src/index.mjs"],
      "env": {
        "HULY_URL": "https://your-huly-instance.com",
        "HULY_EMAIL": "${HULY_EMAIL}",
        "HULY_PASSWORD": "${HULY_PASSWORD}",
        "HULY_WORKSPACE": "${HULY_WORKSPACE}"
      }
    }
  }
}

Then ask Claude things like:

  • "List my issues in the OPS project"
  • "Create a bug report for the login page crash"
  • "Summarize the PROJ project — what's overdue?"
  • "Break down this feature into subtasks using the feature template"

All tools have detailed descriptions optimized for AI agents. MCP Resources are also available at huly://projects/{id} and huly://issues/{id}.

Streamable HTTP (n8n, VS Code, remote clients)

Start the HTTP MCP server:

npm run start:server
# MCP endpoint: http://localhost:3001/mcp
# Health check: http://localhost:3001/health

Any MCP client that supports Streamable HTTP can connect to http://localhost:3001/mcp. This includes n8n (v1.88+), VS Code, and other MCP-compatible tools.

To secure the endpoint, set a bearer token:

MCP_AUTH_TOKEN=your-secret npm run start:server

Clients must then include Authorization: Bearer your-secret in requests.

Docker

docker build -t huly-mcp-server .

# Streamable HTTP server (recommended)
docker run -d \
  -p 3001:3001 \
  -e HULY_URL=https://your-huly-instance.com \
  -e HULY_TOKEN=your-token \
  -e HULY_WORKSPACE=my-workspace \
  huly-mcp-server

# MCP stdio mode
docker run -i \
  -e HULY_URL=https://your-huly-instance.com \
  -e HULY_TOKEN=your-token \
  -e HULY_WORKSPACE=my-workspace \
  huly-mcp-server node src/mcp.mjs

Server Configuration

Environment Variables

| Variable | Required | Default | Description | | --- | --- | --- | --- | | Huly Connection | | | | | HULY_URL | No | http://localhost:8087 | Huly instance URL | | HULY_TOKEN | No | - | Auth token (alternative to email/password) | | HULY_EMAIL | No | - | Huly login email (required if no token) | | HULY_PASSWORD | No | - | Huly login password (required if no token) | | HULY_WORKSPACE | Yes* | - | Default workspace slug | | HULY_TRANSPORT | No | ws | SDK transport: ws (WebSocket) or rest (REST API) | | HULY_POOL_TTL_MS | No | 1800000 | Connection pool TTL in ms (30 min) | | HTTP Server | | | | | PORT | No | 3001 | HTTP server port (auto-assigns if taken) | | MCP_AUTH_TOKEN | No | - | Bearer token for HTTP auth (disabled if unset) | | HULY_RATE_LIMIT | No | 200 | Max requests per minute per IP | | ALLOWED_ORIGINS | No | * | CORS allowed origins (comma-separated) |

*HULY_WORKSPACE is required for MCP stdio mode. For HTTP mode it can be omitted if every request specifies a workspace via the tool arguments.

HTTP Server Authentication

The HTTP server optionally requires a bearer token. This protects your server from unauthorized access — it's separate from Huly's own authentication.

# Generate a token
openssl rand -hex 32

# Start with auth enabled
MCP_AUTH_TOKEN=your-token-here npm run start:server

If MCP_AUTH_TOKEN is not set, auth is disabled (fine for local-only usage).

MCP stdio mode (Claude Code) does not use this token — stdio is inherently local.

Multi-Workspace

All tools accept an optional workspace parameter. The connection pool caches clients by workspace slug with configurable TTL:

{"tool": "list_projects", "arguments": {"workspace": "workspace-a"}}

If omitted, the HULY_WORKSPACE env var is used as the default.


Testing

Uses Node.js built-in node:test and node:assert — no test framework dependencies. Tests run twice: once with WebSocket transport, once with REST transport.

npm test              # Both transports (ws + rest)
npm run test:ws       # WebSocket only
npm run test:rest     # REST only

194 tests across 101 suites:

| Suite | Tests | Description | | --- | --- | --- | | Unit | 28 | Constants, ID parsing, rate limiting, auth logic | | Integration | 55 | Full CRUD lifecycle against live Huly | | Dispatch | 45 | Schema to dispatch to client param forwarding for all tools | | Account-level | 11 | Workspaces, profile, social IDs | | Mock | 44 | Destructive ops, token auth via mocks | | Streamable HTTP | 11 | MCP protocol over HTTP: init, tools, resources, auth, rate limiting |

100% dispatch coverage — every tool's params are traced end-to-end through the dispatch table to the client method.


Network Configurations

  • Local: HULY_URL=http://localhost:8087
  • Remote: HULY_URL=https://huly.example.com
  • Behind nginx proxy: Point to the proxy port

Cloudflare Access / Tunnel

If Huly is behind Cloudflare Access with MFA, create a bypass Application for /_* or these individual paths:

  • /_accounts
  • /_transactor
  • /_collaborator
  • /_rekoni
  • /config.json

Architecture

src/
  client.mjs    # HulyClient — all business logic and SDK calls
  helpers.mjs   # Shared constants, markup conversion, JSDOM polyfills
  dispatch.mjs  # Tool-to-method dispatch table
  pool.mjs      # Connection pool — caches clients by workspace with TTL
  mcpShared.mjs # Shared MCP server factory — tool definitions + resources
  mcp.mjs       # MCP stdio entry point (Claude Code)
  server.mjs    # MCP Streamable HTTP entry point (n8n, VS Code, remote)
  index.mjs     # CLI entry point — --get-token mode + MCP re-export
Claude Code  -> stdio           -> mcp.mjs    -> mcpShared.mjs -> pool -> client -> Huly SDK
n8n / remote -> Streamable HTTP -> server.mjs -> mcpShared.mjs -> pool -> client -> Huly SDK

Response Format

All read operations return known fields at the top level with resolved, human-readable values (e.g., status names instead of IDs, formatted dates). Any additional fields from the Huly SDK that aren't explicitly mapped appear in an extra object — this future-proofs the API so new SDK fields are visible without a code update.

{
  "id": "PROJ-42",
  "title": "Fix the bug",
  "status": "In Progress",
  "priority": "High",
  "type": "Task",
  "parent": "PROJ-10",
  "childCount": 3,
  "createdOn": 1719700000000,
  "completedAt": null,
  "extra": {
    "_id": "69bab168...",
    "_class": "tracker:class:Issue",
    "space": "69b819b7...",
    "kind": "tracker:taskTypes:Issue"
  }
}

Text fields (description, comment) support three input formats via descriptionFormat / format parameter:

  • markdown (default) — rendered as rich text in the Huly UI
  • html — raw HTML, converted to rich text
  • plain — stored as unformatted text

API Reference

Full list of all MCP tools available through this server.

Account and Workspace Management

| Tool | Description | | --- | --- | | list_workspaces | List all accessible workspaces | | get_workspace_info | Get workspace details by slug | | create_workspace | Create a new workspace | | update_workspace_name | Rename a workspace | | delete_workspace | Permanently delete a workspace | | get_workspace_members | List workspace members and roles | | update_workspace_role | Change a member's role | | get_account_info | Get current user's account info | | get_user_profile | Get current user's profile | | set_my_profile | Update profile fields | | change_password | Change password | | change_username | Change username |

Invites

| Tool | Description | | --- | --- | | send_invite | Send workspace invite email | | resend_invite | Resend pending invite | | create_invite_link | Generate shareable invite link |

Integrations, Mailboxes, Social IDs, Subscriptions

| Tool | Description | | --- | --- | | list_integrations / get_integration / create_integration / update_integration / delete_integration | Full CRUD for integrations | | list_mailboxes / create_mailbox / delete_mailbox | Mailbox management | | find_person_by_social_key / get_social_ids / add_email_social_id | Person/social ID management | | list_subscriptions | List account subscriptions |

Projects

| Tool | Description | Text Format | | --- | --- | --- | | list_projects | List all projects (supports include_details) | -- | | get_project | Get project by identifier (supports include_details) | -- | | create_project | Create a new project | descriptionFormat: md/html/plain | | update_project | Update project name, description, privacy, default assignee | descriptionFormat: md/html/plain | | archive_project | Archive or unarchive a project | -- | | delete_project | Permanently delete a project | -- | | summarize_project | Aggregated project metrics and health | -- |

Issues

| Tool | Description | Text Format | | --- | --- | --- | | list_issues | List issues with filters (supports include_details) | -- | | get_issue | Get full issue details (supports include_details) | -- | | create_issue | Create a new issue | descriptionFormat: md/html/plain | | update_issue | Update issue fields | descriptionFormat: md/html/plain | | delete_issue | Permanently delete an issue | -- | | search_issues | Full-text search across projects | -- | | get_my_issues | Issues assigned to current user | -- | | batch_create_issues | Create multiple issues at once | descriptionFormat per item | | move_issue | Move issue between projects | -- | | create_issues_from_template | Create from predefined templates | -- |

Labels

| Tool | Description | | --- | --- | | list_labels | List all labels in the workspace | | get_label | Find a label by name | | create_label | Create a new label with optional color | | update_label | Update label name, color, or description | | delete_label | Permanently delete a label | | add_label | Add a label to an issue | | remove_label | Remove a label from an issue |

Relations

| Tool | Description | | --- | --- | | add_relation | Add bidirectional "related to" link | | add_blocked_by | Add "blocked by" dependency | | set_parent | Set parent issue (epic/task hierarchy) |

Components

| Tool | Description | Text Format | | --- | --- | --- | | list_components | List components in a project | -- | | get_component | Find a component by name | -- | | create_component | Create a new component (optional lead) | descriptionFormat: md/html/plain | | update_component | Update component name, description, or lead | descriptionFormat: md/html/plain | | delete_component | Delete a component | -- |

Milestones

| Tool | Description | Text Format | | --- | --- | --- | | list_milestones | List milestones (supports include_details) | -- | | get_milestone | Get milestone details (supports include_details) | -- | | create_milestone | Create a new milestone | descriptionFormat: md/html/plain | | update_milestone | Update milestone fields | descriptionFormat: md/html/plain | | delete_milestone | Delete a milestone | -- | | set_milestone | Set or clear milestone on an issue | -- |

Members

| Tool | Description | | --- | --- | | list_members | List all active workspace members | | get_member | Find a member by name (fuzzy match) |

Comments

| Tool | Description | Text Format | | --- | --- | --- | | list_comments | List all comments on an issue | -- | | get_comment | Get a specific comment by ID | -- | | add_comment | Add a comment to an issue | format: md/html/plain | | update_comment | Update comment text | format: md/html/plain | | delete_comment | Delete a comment | -- |

Time Tracking

| Tool | Description | Text Format | | --- | --- | --- | | log_time | Log actual time spent | descriptionFormat: md/html/plain | | list_time_reports | List time reports for an issue | -- | | get_time_report | Get a specific time report by ID | -- | | delete_time_report | Delete a time report | -- |

Metadata

| Tool | Description | | --- | --- | | list_task_types | List task types for a project | | get_task_type | Find a task type by name | | list_statuses | List issue statuses | | get_status | Find a status by name |

Text format: All text fields default to markdown. Set descriptionFormat (or format for comments) to "markdown", "html", or "plain". Content is passed through unmodified -- the format tells Huly how to render it.

include_details Flag

Several read tools support an include_details boolean parameter that fetches related data in a single call:

| Tool | Extra data when include_details=true | | --- | --- | | get_issue | Comments, time reports, relations, children | | list_issues | Descriptions, comments, time reports, relations, children (limit reduced to 50) | | get_project | Milestones, components, labels, members | | list_projects | Milestones, components, labels, members per project (limit 20) | | get_milestone | Full list of issues in the milestone | | list_milestones | Issues list per milestone |

CRUD Coverage

| Entity | Create | Read | List | Update | Delete | | --- | --- | --- | --- | --- | --- | | Project | create_project | get_project | list_projects | update_project | delete_project | | Issue | create_issue | get_issue | list_issues | update_issue | delete_issue | | Label | create_label | get_label | list_labels | update_label | delete_label | | Component | create_component | get_component | list_components | update_component | delete_component | | Milestone | create_milestone | get_milestone | list_milestones | update_milestone | delete_milestone | | Comment | add_comment | get_comment | list_comments | update_comment | delete_comment | | Time Report | log_time | get_time_report | list_time_reports | -- | delete_time_report | | Member | -- | get_member | list_members | -- | -- | | Status | -- | get_status | list_statuses | -- | -- | | Task Type | -- | get_task_type | list_task_types | -- | -- |

Issue Templates

Use create_issues_from_template:

| Template | Creates | | --- | --- | | feature | Parent + design/implement/test/docs/review sub-issues | | bug | Parent + reproduce/root-cause/fix/regression-test sub-issues | | sprint | Planning/standup/review/retro ceremony issues | | release | Parent + freeze/QA/changelog/staging/prod/verify sub-issues |

Templates use task types like Epic/Bug when available, falling back to the workspace default type otherwise.


Security

npm audit reports moderate vulnerabilities in Svelte (SSR XSS). These come from Huly SDK transitive dependencies — the SDK shares packages with Huly's web frontend. MCP server never renders HTML or uses Svelte. The vulnerabilities are not exploitable in this context.


License

MIT