Skip to content

Commit 69a8e5b

Browse files
committed
Fix custom fields on task_create for non-default subtypes
Phabricator validates transaction types against the default subtype during creation, so subtype-specific custom fields (e.g. incident fields) fail. Custom fields are now applied in a second maniphest.edit call after creation.
1 parent 4355506 commit 69a8e5b

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@freelancercom/phabricator-mcp",
3-
"version": "2.0.17",
3+
"version": "2.0.18",
44
"description": "MCP server for Phabricator Conduit API - manage tasks, code reviews, repositories, and more",
55
"type": "module",
66
"main": "dist/index.js",

src/tools/maniphest.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -191,28 +191,36 @@ export function registerManiphestTools(server: McpServer, client: ConduitClient)
191191
if (params.comment !== undefined) {
192192
transactions.push({ type: 'comment', value: params.comment });
193193
}
194+
const result = await client.call<{ object: { phid: string; id: number } }>('maniphest.edit', { transactions });
195+
196+
const extras: Record<string, unknown> = {};
197+
198+
// Custom fields are applied in a second call because Phabricator validates
199+
// transaction types against the default subtype during creation. Subtype-specific
200+
// custom fields (e.g. incident fields) are only available after the task exists
201+
// with the correct subtype.
194202
if (params.customFields !== undefined) {
203+
const customTransactions: Array<{ type: string; value: unknown }> = [];
195204
for (const [key, value] of Object.entries(params.customFields)) {
196-
transactions.push({ type: key, value });
205+
customTransactions.push({ type: key, value });
206+
}
207+
if (customTransactions.length > 0) {
208+
extras.customFields = await client.call('maniphest.edit', {
209+
objectIdentifier: result.object.phid,
210+
transactions: customTransactions,
211+
});
197212
}
198213
}
199214

200-
const result = await client.call<{ object: { phid: string; id: number } }>('maniphest.edit', { transactions });
201-
202215
// Link revisions to the newly created task via differential.revision.edit
203216
if (params.revisionIDs !== undefined && params.revisionIDs.length > 0) {
204217
const revPHIDs = await resolveRevisionPHIDs(client, params.revisionIDs);
205218
const taskId = `T${result.object.id}`;
206-
const linkResults = await linkRevisionsToTask(client, taskId, revPHIDs, 'add');
207-
return {
208-
content: [{
209-
type: 'text',
210-
text: JSON.stringify({ ...result, linkedRevisions: linkResults }, null, 2),
211-
}],
212-
};
219+
extras.linkedRevisions = await linkRevisionsToTask(client, taskId, revPHIDs, 'add');
213220
}
214221

215-
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
222+
const output = Object.keys(extras).length > 0 ? { ...result, ...extras } : result;
223+
return { content: [{ type: 'text', text: JSON.stringify(output, null, 2) }] };
216224
},
217225
);
218226

0 commit comments

Comments
 (0)