Install
$ agentstack add skill-joserprieto-ai-skills-huly-api ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: Huly Platform API
Programmatic access to Huly (project management, wiki, tracker) via the @hcengineering/api-client TypeScript library. WebSocket-based, NOT REST.
When to use this skill
- Creating/updating issues, milestones, components in Huly Tracker
- Creating/updating documents in Huly Wiki
- Syncing project state between local files and Huly
- Reading project status from Huly for reporting
- Attaching files (drawio, images, PDFs) to issues or documents
- Configuring project structure (statuses, labels, task types)
Prerequisites
Credentials
Stored in a secure location of your choice — outside the repo, ignored by git, with restricted permissions. Common conventions: ~/.config/huly/credentials.env, a per-project .env.local, or a secrets manager (1Password CLI, pass, gopass, direnv + vault). Reference the path via the HULY_ENV_PATH env var so scripts stay portable.
HULY_EMAIL=
HULY_PASSWORD=password
HULY_URL=https://huly.app
HULY_WORKSPACE=workspace-slug
Load with: require('dotenv').config({ path: process.env.HULY_ENV_PATH })
npm packages
{
"@hcengineering/api-client": "0.7.413",
"@hcengineering/core": "0.7.413",
"@hcengineering/rank": "0.7.413",
"ws": "^8.16.0",
"dotenv": "^16.4.0"
}
CRITICAL: Use exact version 0.7.413. The @hcengineering/tracker and @hcengineering/document packages have broken transitive dependencies — do NOT install them. Use string class IDs instead.
Connection
Preferred: API token (no credentials exposed)
Generate token in Huly: Settings → General → API access → "Generate API token".
const { connect } = require('@hcengineering/api-client');
const { generateId, SortingOrder } = require('@hcengineering/core');
const { makeRank } = require('@hcengineering/rank');
require('dotenv').config({ path: process.env.HULY_ENV_PATH });
const client = await connect(process.env.HULY_URL, {
token: process.env.HULY_API_TOKEN,
workspace: process.env.HULY_WORKSPACE,
connectionTimeout: 30000,
});
// ... work ...
await client.close();
Alternative: email + password (legacy, avoid)
const client = await connect(process.env.HULY_URL, {
email: process.env.HULY_EMAIL,
password: process.env.HULY_PASSWORD,
workspace: process.env.HULY_WORKSPACE,
connectionTimeout: 30000,
});
Ignore no document found warnings — they're internal sync noise, not errors.
Core concepts
Class IDs (use strings, NOT imports)
// Tracker
'tracker:class:Project';
'tracker:class:Issue';
'tracker:class:Milestone';
'tracker:class:Component';
'tracker:taskTypes:Issue'; // kind for issues
// Documents
'document:class:Teamspace';
'document:class:Document';
// Status values (NUMERIC for milestones, STRING refs for issues)
'tracker:status:Backlog'; // issue status
'tracker:status:Todo';
'tracker:status:InProgress';
'tracker:status:Done';
'tracker:status:Canceled';
0; // milestone status: planned (MUST be numeric!)
// Spaces
('core:space:Space'); // parent space for project operations
createDoc vs addCollection
| Entity | Method | Why | | --------- | ------------------- | ------------------------- | | Milestone | createDoc | Direct document | | Component | createDoc | Direct document | | Document | createDoc | Direct document | | Issue | addCollection | Inherits from AttachedDoc |
// Issues MUST use addCollection:
await client.addCollection(
'tracker:class:Issue',
projectId,
projectId,
'tracker:class:Project',
'issues',
{ ...fields },
issueId
);
// Everything else uses createDoc:
await client.createDoc('tracker:class:Milestone', projectId, { ...fields }, msId);
References
- Connection + auth →
references/connection.md - Issues (create, update, list, subtasks) →
references/issues.md - Documents (wiki, content upload) →
references/documents.md - Milestones, Components, project configuration →
references/structure.md - Attachments (files, images, drawio) →
references/attachments.md(work in progress) - Gotchas + known issues →
references/gotchas.md
Source code references (the REAL documentation)
There is NO official API documentation. The source code IS the documentation.
| What | Repository | Path | | ------------------ | ---------------------------------------- | ------------------------- | | Platform core | github.com/hcengineering/huly.core | — | | API client | same repo | packages/api-client/ | | RPC protocol | same repo | packages/rpc/src/rpc.ts | | Tracker model | same repo | models/tracker/ | | Document model | same repo | models/document/ | | Card model | same repo | models/card/ | | API examples | github.com/hcengineering/huly-examples | platform-api/examples/ |
When in doubt about any API behavior, read the source — not the (nonexistent) docs.
Custom classes via API
Card types (MasterTag) can be created programmatically using core:space:Model as the space:
await client.createDoc(
'card:class:MasterTag',
'core:space:Model',
{
label: 'Domain Question',
extends: 'card:class:Card',
kind: 0,
},
generateId()
);
CRITICAL: regular spaces (core:space:Space) won't work for class creation. Must use core:space:Model.
This enables: custom Card types per workspace (Domain Question, Business Rule, Domain Entity, etc.) as reusable templates across client engagements.
Critical gotchas (summary)
See references/gotchas.md for full details.
- Milestone status MUST be numeric (
0= planned). String'planned'silently fails. - Issue status MUST be a tracker status ref (
'tracker:status:Backlog'). Empty string =
invisible.
- Issues use
addCollection, notcreateDoc. Error: "cannot be used for AttachedDoc". - Project type matters: "Classic project" (
tracker:ids:ClassingProjectType) has task types.
Custom project types may have 0 task types → issues invisible in UI.
- DO NOT install
@hcengineering/tracker— broken transitive deps. Use string class IDs. - Content upload: use
client.uploadMarkup(class, id, 'content', markdown, 'markdown')for
rich document content. Plain string in content field won't render formatting.
- Sequence numbers: increment with
client.updateDoc(Project, space, id, { $inc: { sequence: 1 } }, true) and read from result.object.sequence.
- API has NO validation — you can set
status: 'patata'and it'll accept it silently. Always
query valid values first.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: joserprieto
- Source: joserprieto/ai-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.