@freelancercom/phabricator-mcp 2.0.4 → 2.0.6

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 CHANGED
@@ -281,7 +281,8 @@ To allowlist all tools including write operations, use `"mcp__phabricator__*"` i
281
281
  | Tool | Description |
282
282
  |------|-------------|
283
283
  | `phabricator_document_search` | Search wiki documents |
284
- | `phabricator_document_edit` | Create or edit a wiki document |
284
+ | `phabricator_document_create` | Create a new wiki document |
285
+ | `phabricator_document_edit` | Edit a wiki document title or content |
285
286
  | `phabricator_document_add_comment` | Add a comment to a wiki document |
286
287
 
287
288
  ### Blogs (Phame)
@@ -22,13 +22,13 @@ export function registerConpherenceTools(server, client) {
22
22
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
23
23
  });
24
24
  // Read messages in a thread
25
- server.tool('phabricator_conpherence_read', 'Read messages from a Conpherence chat room/thread (returned in reverse chronological order). Uses conpherence.querythread (the only Conduit method that returns message content).', {
25
+ server.tool('phabricator_conpherence_read', 'Read messages from a Conpherence chat room/thread (returned in reverse chronological order). Uses conpherence.querytransaction (the only Conduit method that returns message content).', {
26
26
  roomID: z.coerce.number().describe('Numeric room ID (use phabricator_conpherence_search to find it)'),
27
27
  limit: z.coerce.number().max(100).optional().describe('Maximum messages to return'),
28
28
  offset: z.coerce.number().optional().describe('Result offset for pagination'),
29
29
  }, async (params) => {
30
- const result = await client.call('conpherence.querythread', {
31
- ids: [params.roomID],
30
+ const result = await client.call('conpherence.querytransaction', {
31
+ roomID: params.roomID,
32
32
  limit: params.limit,
33
33
  offset: params.offset,
34
34
  });
@@ -32,11 +32,12 @@ export function registerDiffusionTools(server, client) {
32
32
  constraints: jsonCoerce(z.object({
33
33
  ids: z.array(z.coerce.number()).optional().describe('Commit IDs'),
34
34
  phids: z.array(z.string()).optional().describe('Commit PHIDs'),
35
- repositoryPHIDs: z.array(z.string()).optional().describe('Repository PHIDs'),
35
+ repositories: z.array(z.string()).optional().describe('Repository PHIDs'),
36
36
  identifiers: z.array(z.string()).optional().describe('Commit identifiers (hashes)'),
37
- authorPHIDs: z.array(z.string()).optional().describe('Author PHIDs'),
37
+ authors: z.array(z.string()).optional().describe('Author PHIDs'),
38
+ auditors: z.array(z.string()).optional().describe('Auditor user/project PHIDs'),
38
39
  responsiblePHIDs: z.array(z.string()).optional().describe('User PHIDs responsible (as author or auditor)'),
39
- statuses: z.array(z.string()).optional().describe('Audit statuses: audited, needs-audit, concern-raised, partially-audited'),
40
+ statuses: z.array(z.string()).optional().describe('Audit statuses: none, needs-audit, concern-raised, partially-audited, audited, needs-verification'),
40
41
  query: z.string().optional().describe('Full-text search query'),
41
42
  })).optional().describe('Search constraints'),
42
43
  attachments: jsonCoerce(z.object({
@@ -5,8 +5,8 @@ export function registerFeedTools(server, client) {
5
5
  filterPHIDs: z.array(z.string()).optional().describe('Only show activity involving these PHIDs (user, project, task, etc.)'),
6
6
  view: z.enum(['data', 'text', 'html', 'html-summary']).optional().describe('Output format: "data" (structured, default), "text" (human-readable), "html" (rendered HTML), "html-summary" (title only)'),
7
7
  limit: z.coerce.number().max(100).optional().describe('Maximum results (max 100)'),
8
- after: z.string().optional().describe('Cursor for pagination (chronological key from previous results)'),
9
- before: z.string().optional().describe('Cursor for reverse pagination'),
8
+ after: z.coerce.number().optional().describe('Cursor for pagination (chronological key from previous results)'),
9
+ before: z.coerce.number().optional().describe('Cursor for reverse pagination'),
10
10
  }, async (params) => {
11
11
  const result = await client.call('feed.query', params);
12
12
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
@@ -19,7 +19,7 @@ export function registerFileTools(server, client) {
19
19
  ids: z.array(z.coerce.number()).optional().describe('File IDs'),
20
20
  phids: z.array(z.string()).optional().describe('File PHIDs'),
21
21
  authorPHIDs: z.array(z.string()).optional().describe('Author PHIDs'),
22
- names: z.array(z.string()).optional().describe('File names'),
22
+ name: z.string().optional().describe('File name substring search'),
23
23
  dateCreatedStart: z.coerce.number().optional().describe('Created after (epoch timestamp)'),
24
24
  dateCreatedEnd: z.coerce.number().optional().describe('Created before (epoch timestamp)'),
25
25
  })).optional().describe('Search constraints'),
@@ -11,9 +11,6 @@ export function registerHarbormasterTools(server, client) {
11
11
  containerPHIDs: z.array(z.string()).optional().describe('Container PHIDs'),
12
12
  statuses: z.array(z.string()).optional().describe('Buildable statuses'),
13
13
  })).optional().describe('Search constraints'),
14
- attachments: jsonCoerce(z.object({
15
- builds: z.boolean().optional().describe('Include builds for each buildable'),
16
- })).optional().describe('Data attachments'),
17
14
  order: z.string().optional().describe('Result order'),
18
15
  limit: z.coerce.number().max(100).optional().describe('Maximum results (max 100)'),
19
16
  after: z.string().optional().describe('Cursor for next-page pagination'),
@@ -28,14 +25,11 @@ export function registerHarbormasterTools(server, client) {
28
25
  constraints: jsonCoerce(z.object({
29
26
  ids: z.array(z.coerce.number()).optional().describe('Build IDs'),
30
27
  phids: z.array(z.string()).optional().describe('Build PHIDs'),
31
- buildablePHIDs: z.array(z.string()).optional().describe('Buildable PHIDs'),
32
- buildPlanPHIDs: z.array(z.string()).optional().describe('Build plan PHIDs'),
33
- statuses: z.array(z.string()).optional().describe('Build statuses: building, passed, failed, aborted, error, paused, deadlocked'),
28
+ buildables: z.array(z.string()).optional().describe('Buildable PHIDs'),
29
+ plans: z.array(z.string()).optional().describe('Build plan PHIDs'),
30
+ statuses: z.array(z.string()).optional().describe('Build statuses: building, passed, failed, aborted, error, paused'),
34
31
  initiatorPHIDs: z.array(z.string()).optional().describe('PHIDs of users/objects that initiated the build'),
35
32
  })).optional().describe('Search constraints'),
36
- attachments: jsonCoerce(z.object({
37
- targets: z.boolean().optional().describe('Include build targets for each build'),
38
- })).optional().describe('Data attachments'),
39
33
  order: z.string().optional().describe('Result order'),
40
34
  limit: z.coerce.number().max(100).optional().describe('Maximum results (max 100)'),
41
35
  after: z.string().optional().describe('Cursor for next-page pagination'),
@@ -68,9 +62,6 @@ export function registerHarbormasterTools(server, client) {
68
62
  phids: z.array(z.string()).optional().describe('Log PHIDs'),
69
63
  buildTargetPHIDs: z.array(z.string()).optional().describe('Build target PHIDs'),
70
64
  })).optional().describe('Search constraints'),
71
- attachments: jsonCoerce(z.object({
72
- content: z.boolean().optional().describe('Include actual log text content'),
73
- })).optional().describe('Data attachments'),
74
65
  order: z.string().optional().describe('Result order'),
75
66
  limit: z.coerce.number().max(100).optional().describe('Maximum results (max 100)'),
76
67
  after: z.string().optional().describe('Cursor for next-page pagination'),
@@ -122,8 +113,8 @@ export function registerHarbormasterTools(server, client) {
122
113
  constraints: jsonCoerce(z.object({
123
114
  ids: z.array(z.coerce.number()).optional().describe('Build plan IDs'),
124
115
  phids: z.array(z.string()).optional().describe('Build plan PHIDs'),
125
- statuses: z.array(z.string()).optional().describe('Plan statuses'),
126
- query: z.string().optional().describe('Full-text search query'),
116
+ status: z.array(z.string()).optional().describe('Plan statuses: "active", "disabled"'),
117
+ match: z.string().optional().describe('Search for build plans by name substring'),
127
118
  })).optional().describe('Search constraints'),
128
119
  order: z.string().optional().describe('Result order'),
129
120
  limit: z.coerce.number().max(100).optional().describe('Maximum results (max 100)'),
@@ -13,7 +13,7 @@ export function registerManiphestTools(server, client) {
13
13
  priorities: z.array(z.coerce.number()).optional().describe('Priority levels'),
14
14
  subtypes: z.array(z.string()).optional().describe('Task subtypes'),
15
15
  columnPHIDs: z.array(z.string()).optional().describe('Workboard column PHIDs'),
16
- projectPHIDs: z.array(z.string()).optional().describe('Project PHIDs (tasks tagged with these projects)'),
16
+ projects: z.array(z.string()).optional().describe('Project PHIDs (tasks tagged with these projects)'),
17
17
  query: z.string().optional().describe('Full-text search query'),
18
18
  createdStart: z.coerce.number().optional().describe('Created after (epoch timestamp)'),
19
19
  createdEnd: z.coerce.number().optional().describe('Created before (epoch timestamp)'),
@@ -8,8 +8,8 @@ export function registerOwnersTools(server, client) {
8
8
  ids: z.array(z.coerce.number()).optional().describe('Package IDs'),
9
9
  phids: z.array(z.string()).optional().describe('Package PHIDs'),
10
10
  owners: z.array(z.string()).optional().describe('Owner user or project PHIDs'),
11
- repositoryPHIDs: z.array(z.string()).optional().describe('Repository PHIDs'),
12
- paths: z.array(z.array(z.string())).optional().describe('Code paths as [repositoryPHID, path] pairs (e.g. [["PHID-REPO-xxx", "/src/foo.ts"]])'),
11
+ repositories: z.array(z.string()).optional().describe('Repository PHIDs'),
12
+ paths: z.array(z.string()).optional().describe('Code paths to search for (e.g. "/src/foo.ts")'),
13
13
  statuses: z.array(z.string()).optional().describe('Package statuses'),
14
14
  dominion: z.array(z.string()).optional().describe('Ownership strength: "strong" (default) or "weak"'),
15
15
  autoReview: z.array(z.string()).optional().describe('Auto-review setting: "none", "subscribe", "review", "block"'),
@@ -7,7 +7,7 @@ export function registerPasteTools(server, client) {
7
7
  constraints: jsonCoerce(z.object({
8
8
  ids: z.array(z.coerce.number()).optional().describe('Paste IDs'),
9
9
  phids: z.array(z.string()).optional().describe('Paste PHIDs'),
10
- authorPHIDs: z.array(z.string()).optional().describe('Author PHIDs'),
10
+ authors: z.array(z.string()).optional().describe('Author PHIDs'),
11
11
  languages: z.array(z.string()).optional().describe('Languages'),
12
12
  statuses: z.array(z.string()).optional().describe('Statuses: active, archived'),
13
13
  query: z.string().optional().describe('Full-text search query'),
@@ -12,6 +12,7 @@ export function registerPhameTools(server, client) {
12
12
  })).optional().describe('Search constraints'),
13
13
  attachments: jsonCoerce(z.object({
14
14
  subscribers: z.boolean().optional().describe('Include subscriber details'),
15
+ projects: z.boolean().optional().describe('Include tagged projects'),
15
16
  })).optional().describe('Data attachments'),
16
17
  order: z.string().optional().describe('Result order'),
17
18
  limit: z.coerce.number().max(100).optional().describe('Maximum results (max 100)'),
@@ -29,11 +30,12 @@ export function registerPhameTools(server, client) {
29
30
  phids: z.array(z.string()).optional().describe('Post PHIDs'),
30
31
  blogPHIDs: z.array(z.string()).optional().describe('Filter by blog PHIDs'),
31
32
  authorPHIDs: z.array(z.string()).optional().describe('Filter by author PHIDs'),
32
- visibility: z.array(z.coerce.number()).optional().describe('Visibility: 1 (published), 0 (draft), 2 (archived). Note: use these numeric codes in search; use string names like "published" in create/edit.'),
33
+ visibility: z.array(z.string()).optional().describe('Visibility: "published", "draft", "archived" (or numeric: "1", "0", "2")'),
33
34
  query: z.string().optional().describe('Full-text search query'),
34
35
  })).optional().describe('Search constraints'),
35
36
  attachments: jsonCoerce(z.object({
36
- content: z.boolean().optional().describe('Include blog post body content'),
37
+ subscribers: z.boolean().optional().describe('Include subscriber details'),
38
+ projects: z.boolean().optional().describe('Include tagged projects'),
37
39
  })).optional().describe('Data attachments'),
38
40
  order: z.string().optional().describe('Result order'),
39
41
  limit: z.coerce.number().max(100).optional().describe('Maximum results (max 100)'),
@@ -26,42 +26,24 @@ export function registerPhrictionTools(server, client) {
26
26
  const result = await client.call('phriction.document.search', params);
27
27
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
28
28
  });
29
- // Edit wiki document
30
- server.tool('phabricator_document_edit', 'Create or edit a Phriction wiki document. To create, provide a new slug with title and content.', {
31
- objectIdentifier: z.string().describe('Document slug, PHID, or ID (e.g., "projects/myproject/")'),
32
- title: z.string().optional().describe('Document title'),
33
- content: z.string().optional().describe('Document content (Remarkup)'),
34
- delete: z.boolean().optional().describe('Set to true to delete/archive the document'),
35
- move: z.string().optional().describe('New slug to move/rename the document to'),
36
- addSubscriberPHIDs: z.array(z.string()).optional().describe('Subscriber PHIDs to add'),
37
- removeSubscriberPHIDs: z.array(z.string()).optional().describe('Subscriber PHIDs to remove'),
29
+ // Create wiki document
30
+ server.tool('phabricator_document_create', 'Create a new Phriction wiki document. Uses phriction.create (the only method that can create documents).', {
31
+ slug: z.string().describe('Document slug/path (e.g., "projects/myproject/")'),
32
+ title: z.string().describe('Document title'),
33
+ content: z.string().describe('Document content (Remarkup)'),
34
+ description: z.string().optional().describe('Edit description/summary'),
38
35
  }, async (params) => {
39
- const transactions = [];
40
- if (params.title !== undefined) {
41
- transactions.push({ type: 'title', value: params.title });
42
- }
43
- if (params.content !== undefined) {
44
- transactions.push({ type: 'content', value: params.content });
45
- }
46
- if (params.delete === true) {
47
- transactions.push({ type: 'delete', value: true });
48
- }
49
- if (params.move !== undefined) {
50
- transactions.push({ type: 'move', value: params.move });
51
- }
52
- if (params.addSubscriberPHIDs !== undefined) {
53
- transactions.push({ type: 'subscribers.add', value: params.addSubscriberPHIDs });
54
- }
55
- if (params.removeSubscriberPHIDs !== undefined) {
56
- transactions.push({ type: 'subscribers.remove', value: params.removeSubscriberPHIDs });
57
- }
58
- if (transactions.length === 0) {
59
- return { content: [{ type: 'text', text: 'No changes specified' }] };
60
- }
61
- const result = await client.call('phriction.document.edit', {
62
- objectIdentifier: params.objectIdentifier,
63
- transactions,
64
- });
36
+ const result = await client.call('phriction.create', params);
37
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
38
+ });
39
+ // Edit wiki document content
40
+ server.tool('phabricator_document_edit', 'Edit an existing Phriction wiki document title or content. Uses phriction.edit (the only method that can update document content).', {
41
+ slug: z.string().describe('Document slug/path (e.g., "projects/myproject/")'),
42
+ title: z.string().optional().describe('New document title'),
43
+ content: z.string().optional().describe('New document content (Remarkup)'),
44
+ description: z.string().optional().describe('Edit description/summary'),
45
+ }, async (params) => {
46
+ const result = await client.call('phriction.edit', params);
65
47
  return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
66
48
  });
67
49
  // Add comment to document
@@ -8,7 +8,8 @@ export function registerTransactionTools(server, client) {
8
8
  authorPHIDs: z.array(z.string()).optional().describe('Author PHIDs'),
9
9
  })).optional().describe('Search constraints'),
10
10
  limit: z.coerce.number().max(100).optional().describe('Maximum results (max 100)'),
11
- after: z.string().optional().describe('Pagination cursor'),
11
+ after: z.string().optional().describe('Cursor for next-page pagination'),
12
+ before: z.string().optional().describe('Cursor for previous-page pagination'),
12
13
  }, async (params) => {
13
14
  const { objectIdentifier, ...searchParams } = params;
14
15
  const result = await client.call('transaction.search', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freelancercom/phabricator-mcp",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "MCP server for Phabricator Conduit API - manage tasks, code reviews, repositories, and more",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",