huly-mcp
by MinaFikry
README.md
# Huly MCP Server
This is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for the **Huly** project and document management platform, allowing AI assistants such as **Claude Code** and **Codex** to interact with Huly directly.
## What is MCP?
Model Context Protocol (MCP) allows AI assistants to access external tools through a standardized interface. This server implements the MCP specification and talks to Huly through its official `@hcengineering` client SDK over WebSocket. It runs locally as a **stdio** server — the AI assistant launches it and communicates over standard input/output. There is no HTTP endpoint to host or expose.
## Features
This MCP server provides access to the following Huly functionalities.
### Search Actions
- **List Projects**: Retrieve all tracker projects and their identifiers.
- **Search Issues**: Find issues in a project with rich filters — title, assignee, unassigned, status, priority, component, milestone, label, parent (sub-issues), modified-after, and due-before.
- **Get Issue**: Fetch full detail of a single issue: markdown description, labels, parent/sub-issues, and comment & attachment counts.
- **List Persons**: Fetch workspace people, filtered by name.
- **List Statuses**: List workflow statuses (Todo, In Progress, Done…).
- **List Components / Milestones / Labels**: List a project's components, milestones, and available labels.
- **List Comments / Attachments**: Read an issue's comments (markdown, with author names) and its attachments.
### Write Actions
- **Create Issue**: Create a new issue under a project with title, markdown description, assignee, priority, component, milestone, due date, status, and optional parent (sub-issue).
- **Update Issue**: Change any field of an issue — title, description, assignee, status, priority, component, milestone, due date, or estimation.
- **Delete Issue**: Permanently remove an issue.
- **Add Comment**: Post a markdown comment on an issue.
- **Add Attachment**: Upload a local file as an attachment on an issue.
- **Add / Remove Label**: Attach or remove a label (auto-creates the tag if it doesn't exist).
- **Create Milestone**: Create a new milestone inside a project.
## Installation
```bash
# Clone the repository
git clone <REPO_URL> huly-mcp-server
# Navigate to the project directory
cd huly-mcp-server
# Install dependencies
npm install
```
> No build step is required — the server is plain ES-module JavaScript and runs directly on Node.js (≥ 18).
## Usage
### Configuration
The server is configured with environment variables (or a local `.env` file — copy `.env.example` to `.env`):
| Variable | Description | Default |
|----------|-------------|---------|
| `HULY_URL` | Base URL of the Huly instance | `https://your-huly-instance.com` |
| `HULY_WORKSPACE` | Workspace identifier | `your-workspace-name` |
| `HULY_TOKEN` | Personal workspace token (**recommended**) | — |
| `HULY_EMAIL` / `HULY_PASSWORD` | Login used only as a fallback to mint a token | — |
### Getting your token
You authenticate with a personal token so your password never lives in any config file:
```bash
cp .env.example .env # then fill in HULY_EMAIL and HULY_PASSWORD
npm run token # prints your personal HULY_TOKEN
```
Paste the printed token into `.env` as `HULY_TOKEN=...` and into your AI assistant's MCP config (below).
### Running the server
The server is normally launched by your AI assistant, but you can start it manually to verify it connects:
```bash
npm start
```
## Setup in Claude Code
```bash
claude mcp add huly \
--env HULY_URL=https://your-huly-instance.com \
--env HULY_WORKSPACE=your-workspace-name \
--env HULY_TOKEN=PASTE_YOUR_TOKEN_HERE \
-- node /absolute/path/to/huly-mcp-server/server.js
```
Or add it manually to `~/.claude.json` under `mcpServers`:
```json
{
"mcpServers": {
"huly": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/huly-mcp-server/server.js"],
"env": {
"HULY_URL": "https://your-huly-instance.com",
"HULY_WORKSPACE": "your-workspace-name",
"HULY_TOKEN": "PASTE_YOUR_TOKEN_HERE"
}
}
}
}
```
Restart Claude Code, then verify with `claude mcp list`.
## Setup in Codex
```bash
codex mcp add huly \
--env HULY_URL=https://your-huly-instance.com \
--env HULY_WORKSPACE=your-workspace-name \
--env HULY_TOKEN=PASTE_YOUR_TOKEN_HERE \
-- node /absolute/path/to/huly-mcp-server/server.js
```
Or add it manually to `~/.codex/config.toml`:
```toml
[mcp_servers.huly]
command = "node"
args = ["/absolute/path/to/huly-mcp-server/server.js"]
[mcp_servers.huly.env]
HULY_URL = "https://your-huly-instance.com"
HULY_WORKSPACE = "your-workspace-name"
HULY_TOKEN = "PASTE_YOUR_TOKEN_HERE"
```
Restart Codex, then verify with `codex mcp list`.
## Development
### Project Structure
```
huly-mcp-server/
├── server.js # MCP server — all tool definitions and Huly client wiring
├── get-token.js # Mints a personal workspace token from email + password
├── .env.example # Configuration template (copy to .env)
├── .gitignore # Excludes .env, tokens, and node_modules
├── package.json # Pinned dependencies and npm scripts
└── README.md
```
Each tool is defined in `server.js` as a `server.tool(name, description, schema, handler)` block. Handlers are wrapped in a `guard()` helper so thrown errors become clean MCP error responses instead of crashing the process.
### Notes for maintainers
Discovered against our Huly instance (server `0.7.242`, client `0.7.423`):
- **Do not use the SDK `markdown()` helper** with `createDoc` / `updateDoc` / `addCollection`. In client `0.7.423`, `processMarkup` assigns the upload *promise* without awaiting it, storing `{}` instead of a markup ref. Call `await client.uploadMarkup(...)` explicitly and pass the returned ref.
- **Comment authors**: `createdBy` is a social id — resolve via `contact.class.SocialIdentity` → `Person`, not `personUuid`.
- **Person names** are stored `"LastName,FirstName"` — match by substring.
## Testing
Run the server manually and confirm it connects and lists tools:
```bash
npm start
```
There is no automated test suite yet. Contributions adding one are welcome.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the MIT License.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues