@firfi/huly-mcp 0.1.30 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +88 -36
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -149,7 +149,7 @@ MCP_TRANSPORT=http MCP_HTTP_PORT=8080 MCP_HTTP_HOST=0.0.0.0 npx -y @firfi/huly-m
|
|
|
149
149
|
|------|-------------|
|
|
150
150
|
| `list_issues` | Query Huly issues with optional filters. Returns issues sorted by modification date (newest first). Supports filtering by project, status, assignee, and milestone. Supports searching by title substring (titleSearch) and description content (descriptionSearch). |
|
|
151
151
|
| `get_issue` | Retrieve full details for a Huly issue including markdown description. Use this to view issue content, comments, or full metadata. |
|
|
152
|
-
| `create_issue` | Create a new issue in a Huly project. Description supports markdown formatting. Returns the created issue identifier. |
|
|
152
|
+
| `create_issue` | Create a new issue in a Huly project. Optionally create as a sub-issue by specifying parentIssue. Description supports markdown formatting. Returns the created issue identifier. |
|
|
153
153
|
| `update_issue` | Update fields on an existing Huly issue. Only provided fields are modified. Description updates support markdown. |
|
|
154
154
|
| `add_issue_label` | Add a tag/label to a Huly issue. Creates the tag if it doesn't exist in the project. |
|
|
155
155
|
| `delete_issue` | Permanently delete a Huly issue. This action cannot be undone. |
|
package/dist/index.cjs
CHANGED
|
@@ -154203,11 +154203,10 @@ var parseIssueIdentifier = (identifier2, projectIdentifier) => {
|
|
|
154203
154203
|
}
|
|
154204
154204
|
return { fullIdentifier: idStr, number: null };
|
|
154205
154205
|
};
|
|
154206
|
-
var
|
|
154207
|
-
const { client, project: project3 } = yield* findProject(params.project);
|
|
154206
|
+
var findIssueInProject = (client, project3, identifierStr) => Effect_exports.gen(function* () {
|
|
154208
154207
|
const { fullIdentifier, number: number8 } = parseIssueIdentifier(
|
|
154209
|
-
|
|
154210
|
-
|
|
154208
|
+
identifierStr,
|
|
154209
|
+
project3.identifier
|
|
154211
154210
|
);
|
|
154212
154211
|
let issue2 = yield* client.findOne(
|
|
154213
154212
|
tracker.class.Issue,
|
|
@@ -154227,10 +154226,15 @@ var findProjectAndIssue = (params) => Effect_exports.gen(function* () {
|
|
|
154227
154226
|
}
|
|
154228
154227
|
if (issue2 === void 0) {
|
|
154229
154228
|
return yield* new IssueNotFoundError({
|
|
154230
|
-
identifier:
|
|
154231
|
-
project:
|
|
154229
|
+
identifier: identifierStr,
|
|
154230
|
+
project: project3.identifier
|
|
154232
154231
|
});
|
|
154233
154232
|
}
|
|
154233
|
+
return issue2;
|
|
154234
|
+
});
|
|
154235
|
+
var findProjectAndIssue = (params) => Effect_exports.gen(function* () {
|
|
154236
|
+
const { client, project: project3 } = yield* findProject(params.project);
|
|
154237
|
+
const issue2 = yield* findIssueInProject(client, project3, params.identifier);
|
|
154234
154238
|
return { client, project: project3, issue: issue2 };
|
|
154235
154239
|
});
|
|
154236
154240
|
var priorityToStringMap = {
|
|
@@ -173659,7 +173663,7 @@ var PostHog = class extends PostHogBackendClient {
|
|
|
173659
173663
|
};
|
|
173660
173664
|
|
|
173661
173665
|
// src/version.ts
|
|
173662
|
-
var VERSION = true ? "0.1.
|
|
173666
|
+
var VERSION = true ? "0.1.32" : "0.0.0-dev";
|
|
173663
173667
|
|
|
173664
173668
|
// src/telemetry/posthog.ts
|
|
173665
173669
|
var POSTHOG_API_KEY = "phc_TGfFqCGdnF0p68wuFzd5WSw1IsBvOJW0YgoMJDyZPjm";
|
|
@@ -173680,6 +173684,7 @@ var createPostHogTelemetry = (debug) => {
|
|
|
173680
173684
|
properties: {
|
|
173681
173685
|
session_id: sessionId,
|
|
173682
173686
|
version: VERSION,
|
|
173687
|
+
$ip: null,
|
|
173683
173688
|
...properties
|
|
173684
173689
|
}
|
|
173685
173690
|
});
|
|
@@ -173769,22 +173774,6 @@ var TelemetryService = class _TelemetryService extends Context_exports.Tag("@hul
|
|
|
173769
173774
|
}
|
|
173770
173775
|
};
|
|
173771
173776
|
|
|
173772
|
-
// src/utils/assertions.ts
|
|
173773
|
-
var AssertionError = class extends Error {
|
|
173774
|
-
_tag = "AssertionError";
|
|
173775
|
-
constructor(message) {
|
|
173776
|
-
super(message);
|
|
173777
|
-
this.name = "AssertionError";
|
|
173778
|
-
}
|
|
173779
|
-
};
|
|
173780
|
-
var assertExists = (value3, message) => {
|
|
173781
|
-
if (value3 === null || value3 === void 0) {
|
|
173782
|
-
throw new AssertionError(message ?? "Expected value to exist");
|
|
173783
|
-
}
|
|
173784
|
-
return value3;
|
|
173785
|
-
};
|
|
173786
|
-
var isExistent = (value3) => value3 !== null && value3 !== void 0;
|
|
173787
|
-
|
|
173788
173777
|
// src/mcp/error-mapping.ts
|
|
173789
173778
|
var McpErrorCode = {
|
|
173790
173779
|
InvalidParams: -32602,
|
|
@@ -176005,11 +175994,30 @@ var listProjectsParamsJsonSchema = JSONSchema_exports.make(ListProjectsParamsSch
|
|
|
176005
175994
|
var parseListProjectsParams = Schema_exports.decodeUnknown(ListProjectsParamsSchema);
|
|
176006
175995
|
var parseProject = Schema_exports.decodeUnknown(ProjectSchema);
|
|
176007
175996
|
|
|
175997
|
+
// src/utils/normalize.ts
|
|
175998
|
+
var normalizeForComparison = (s) => s.replace(/[-_ ]/g, "").toLowerCase();
|
|
175999
|
+
|
|
176008
176000
|
// src/domain/schemas/issues.ts
|
|
176009
176001
|
var IssuePriorityValues = ["urgent", "high", "medium", "low", "no-priority"];
|
|
176010
|
-
var
|
|
176002
|
+
var IssuePriorityLiteral = Schema_exports.Literal(...IssuePriorityValues);
|
|
176003
|
+
var normalizedPriorityLookup = new Map(
|
|
176004
|
+
IssuePriorityValues.map((v) => [normalizeForComparison(v), v])
|
|
176005
|
+
);
|
|
176006
|
+
var IssuePrioritySchema = Schema_exports.transformOrFail(
|
|
176007
|
+
Schema_exports.String,
|
|
176008
|
+
IssuePriorityLiteral,
|
|
176009
|
+
{
|
|
176010
|
+
strict: true,
|
|
176011
|
+
decode: (input, _options, ast) => {
|
|
176012
|
+
const match16 = normalizedPriorityLookup.get(normalizeForComparison(input));
|
|
176013
|
+
return match16 !== void 0 ? ParseResult_exports.succeed(match16) : ParseResult_exports.fail(new ParseResult_exports.Type(ast, input, `Expected one of: ${IssuePriorityValues.join(", ")}`));
|
|
176014
|
+
},
|
|
176015
|
+
encode: ParseResult_exports.succeed
|
|
176016
|
+
}
|
|
176017
|
+
).annotations({
|
|
176011
176018
|
title: "IssuePriority",
|
|
176012
|
-
description: "Issue priority level"
|
|
176019
|
+
description: "Issue priority level",
|
|
176020
|
+
jsonSchema: { type: "string", enum: [...IssuePriorityValues] }
|
|
176013
176021
|
});
|
|
176014
176022
|
var LabelSchema = Schema_exports.Struct({
|
|
176015
176023
|
title: NonEmptyString2,
|
|
@@ -176112,6 +176120,9 @@ var CreateIssueParamsSchema = Schema_exports.Struct({
|
|
|
176112
176120
|
})),
|
|
176113
176121
|
status: Schema_exports.optional(StatusName.annotations({
|
|
176114
176122
|
description: "Initial status (uses project default if not specified)"
|
|
176123
|
+
})),
|
|
176124
|
+
parentIssue: Schema_exports.optional(IssueIdentifier.annotations({
|
|
176125
|
+
description: "Parent issue identifier (e.g., 'HULY-42') to create as sub-issue"
|
|
176115
176126
|
}))
|
|
176116
176127
|
}).annotations({
|
|
176117
176128
|
title: "CreateIssueParams",
|
|
@@ -179298,6 +179309,24 @@ var documentTools = [
|
|
|
179298
179309
|
|
|
179299
179310
|
// src/huly/operations/components.ts
|
|
179300
179311
|
var import_core27 = __toESM(require_lib4(), 1);
|
|
179312
|
+
|
|
179313
|
+
// src/utils/assertions.ts
|
|
179314
|
+
var AssertionError = class extends Error {
|
|
179315
|
+
_tag = "AssertionError";
|
|
179316
|
+
constructor(message) {
|
|
179317
|
+
super(message);
|
|
179318
|
+
this.name = "AssertionError";
|
|
179319
|
+
}
|
|
179320
|
+
};
|
|
179321
|
+
var assertExists = (value3, message) => {
|
|
179322
|
+
if (value3 === null || value3 === void 0) {
|
|
179323
|
+
throw new AssertionError(message ?? "Expected value to exist");
|
|
179324
|
+
}
|
|
179325
|
+
return value3;
|
|
179326
|
+
};
|
|
179327
|
+
var isExistent = (value3) => value3 !== null && value3 !== void 0;
|
|
179328
|
+
|
|
179329
|
+
// src/huly/operations/components.ts
|
|
179301
179330
|
var findComponentByIdOrLabel = (client, projectId, componentIdOrLabel) => Effect_exports.gen(function* () {
|
|
179302
179331
|
let component = yield* client.findOne(
|
|
179303
179332
|
tracker.class.Component,
|
|
@@ -179487,8 +179516,9 @@ var extractUpdatedSequence = (txResult) => {
|
|
|
179487
179516
|
return decoded._tag === "Some" ? decoded.value.object.sequence : void 0;
|
|
179488
179517
|
};
|
|
179489
179518
|
var resolveStatusByName = (statuses, statusName, project3) => {
|
|
179519
|
+
const normalizedInput = normalizeForComparison(statusName);
|
|
179490
179520
|
const matchingStatus = statuses.find(
|
|
179491
|
-
(s) => s.name
|
|
179521
|
+
(s) => normalizeForComparison(s.name) === normalizedInput
|
|
179492
179522
|
);
|
|
179493
179523
|
if (matchingStatus === void 0) {
|
|
179494
179524
|
return Effect_exports.fail(new InvalidStatusError({ status: statusName, project: project3 }));
|
|
@@ -179519,7 +179549,7 @@ var listIssues = (params) => Effect_exports.gen(function* () {
|
|
|
179519
179549
|
space: project3._id
|
|
179520
179550
|
};
|
|
179521
179551
|
if (params.status !== void 0) {
|
|
179522
|
-
const statusFilter = params.status
|
|
179552
|
+
const statusFilter = normalizeForComparison(params.status);
|
|
179523
179553
|
if (statusFilter === "open") {
|
|
179524
179554
|
const doneAndCanceledStatuses = statuses.filter((s) => s.isDone || s.isCanceled).map((s) => s._id);
|
|
179525
179555
|
if (doneAndCanceledStatuses.length > 0) {
|
|
@@ -179696,6 +179726,25 @@ var createIssue = (params) => Effect_exports.gen(function* () {
|
|
|
179696
179726
|
}
|
|
179697
179727
|
const priority = stringToPriority(params.priority || "no-priority");
|
|
179698
179728
|
const identifier2 = `${project3.identifier}-${sequence}`;
|
|
179729
|
+
let attachedTo = project3._id;
|
|
179730
|
+
let attachedToClass = tracker.class.Project;
|
|
179731
|
+
let collection = "issues";
|
|
179732
|
+
let parents = [];
|
|
179733
|
+
if (params.parentIssue !== void 0) {
|
|
179734
|
+
const parentIssue = yield* findIssueInProject(client, project3, params.parentIssue);
|
|
179735
|
+
attachedTo = parentIssue._id;
|
|
179736
|
+
attachedToClass = tracker.class.Issue;
|
|
179737
|
+
collection = "subIssues";
|
|
179738
|
+
parents = [
|
|
179739
|
+
...parentIssue.parents,
|
|
179740
|
+
{
|
|
179741
|
+
parentId: parentIssue._id,
|
|
179742
|
+
identifier: parentIssue.identifier,
|
|
179743
|
+
parentTitle: parentIssue.title,
|
|
179744
|
+
space: project3._id
|
|
179745
|
+
}
|
|
179746
|
+
];
|
|
179747
|
+
}
|
|
179699
179748
|
const issueData = {
|
|
179700
179749
|
title: params.title,
|
|
179701
179750
|
description: descriptionMarkupRef,
|
|
@@ -179711,7 +179760,7 @@ var createIssue = (params) => Effect_exports.gen(function* () {
|
|
|
179711
179760
|
reportedTime: 0,
|
|
179712
179761
|
reports: 0,
|
|
179713
179762
|
subIssues: 0,
|
|
179714
|
-
parents
|
|
179763
|
+
parents,
|
|
179715
179764
|
childInfo: [],
|
|
179716
179765
|
dueDate: null,
|
|
179717
179766
|
rank
|
|
@@ -179719,9 +179768,9 @@ var createIssue = (params) => Effect_exports.gen(function* () {
|
|
|
179719
179768
|
yield* client.addCollection(
|
|
179720
179769
|
tracker.class.Issue,
|
|
179721
179770
|
project3._id,
|
|
179722
|
-
|
|
179723
|
-
|
|
179724
|
-
|
|
179771
|
+
attachedTo,
|
|
179772
|
+
attachedToClass,
|
|
179773
|
+
collection,
|
|
179725
179774
|
issueData,
|
|
179726
179775
|
issueId
|
|
179727
179776
|
);
|
|
@@ -180117,7 +180166,7 @@ var issueTools = [
|
|
|
180117
180166
|
},
|
|
180118
180167
|
{
|
|
180119
180168
|
name: "create_issue",
|
|
180120
|
-
description: "Create a new issue in a Huly project. Description supports markdown formatting. Returns the created issue identifier.",
|
|
180169
|
+
description: "Create a new issue in a Huly project. Optionally create as a sub-issue by specifying parentIssue. Description supports markdown formatting. Returns the created issue identifier.",
|
|
180121
180170
|
category: CATEGORY8,
|
|
180122
180171
|
inputSchema: createIssueParamsJsonSchema,
|
|
180123
180172
|
handler: createToolHandler(
|
|
@@ -181807,10 +181856,10 @@ var McpServerService = class _McpServerService extends Context_exports.Tag("@hul
|
|
|
181807
181856
|
toolCount: registry2.definitions.length,
|
|
181808
181857
|
toolsets
|
|
181809
181858
|
});
|
|
181810
|
-
const server = config3.transport === "stdio" ? createMcpServer(hulyClient, storageClient, telemetry, registry2, workspaceClient) : null;
|
|
181811
181859
|
const flushTelemetry = Effect_exports.ignore(
|
|
181812
181860
|
Effect_exports.tryPromise(() => telemetry.shutdown())
|
|
181813
181861
|
);
|
|
181862
|
+
const serverRef = yield* Ref_exports.make(null);
|
|
181814
181863
|
const isRunning2 = yield* Ref_exports.make(false);
|
|
181815
181864
|
const operations = {
|
|
181816
181865
|
run: () => Effect_exports.gen(function* () {
|
|
@@ -181821,8 +181870,9 @@ var McpServerService = class _McpServerService extends Context_exports.Tag("@hul
|
|
|
181821
181870
|
}
|
|
181822
181871
|
yield* Ref_exports.set(isRunning2, true);
|
|
181823
181872
|
if (config3.transport === "stdio") {
|
|
181873
|
+
const stdioServer = createMcpServer(hulyClient, storageClient, telemetry, registry2, workspaceClient);
|
|
181874
|
+
yield* Ref_exports.set(serverRef, stdioServer);
|
|
181824
181875
|
const transport = new StdioServerTransport();
|
|
181825
|
-
const stdioServer = assertExists(server, "server must exist for stdio transport");
|
|
181826
181876
|
yield* Effect_exports.tryPromise({
|
|
181827
181877
|
try: () => stdioServer.connect(transport),
|
|
181828
181878
|
catch: (e) => new McpServerError({
|
|
@@ -181883,14 +181933,16 @@ var McpServerService = class _McpServerService extends Context_exports.Tag("@hul
|
|
|
181883
181933
|
}
|
|
181884
181934
|
yield* Ref_exports.set(isRunning2, false);
|
|
181885
181935
|
yield* flushTelemetry;
|
|
181886
|
-
|
|
181936
|
+
const runningServer = yield* Ref_exports.get(serverRef);
|
|
181937
|
+
if (runningServer !== null) {
|
|
181887
181938
|
yield* Effect_exports.tryPromise({
|
|
181888
|
-
try: () =>
|
|
181939
|
+
try: () => runningServer.close(),
|
|
181889
181940
|
catch: (e) => new McpServerError({
|
|
181890
181941
|
message: `Failed to stop server: ${String(e)}`,
|
|
181891
181942
|
cause: e
|
|
181892
181943
|
})
|
|
181893
181944
|
});
|
|
181945
|
+
yield* Ref_exports.set(serverRef, null);
|
|
181894
181946
|
}
|
|
181895
181947
|
})
|
|
181896
181948
|
};
|