@ezmodo/mcp-server 0.13.0

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.
Files changed (98) hide show
  1. package/README.md +305 -0
  2. package/config/development.js +20 -0
  3. package/config/endpoint-map.js +351 -0
  4. package/config/index.js +34 -0
  5. package/config/production.js +18 -0
  6. package/config/staging.js +18 -0
  7. package/handlers/access.js +141 -0
  8. package/handlers/activity.js +112 -0
  9. package/handlers/agents.js +95 -0
  10. package/handlers/ai-intelligence.js +55 -0
  11. package/handlers/attachments.js +30 -0
  12. package/handlers/catalogs.js +169 -0
  13. package/handlers/components.js +282 -0
  14. package/handlers/context-manifest.js +1150 -0
  15. package/handlers/decisions.js +114 -0
  16. package/handlers/designs.js +118 -0
  17. package/handlers/documents.js +227 -0
  18. package/handlers/entities.js +95 -0
  19. package/handlers/epics.js +190 -0
  20. package/handlers/facts.js +62 -0
  21. package/handlers/feature-flags.js +142 -0
  22. package/handlers/features.js +137 -0
  23. package/handlers/folders.js +127 -0
  24. package/handlers/git-context.js +917 -0
  25. package/handlers/github.js +72 -0
  26. package/handlers/graph.js +23 -0
  27. package/handlers/index.js +205 -0
  28. package/handlers/links.js +156 -0
  29. package/handlers/milestones.js +131 -0
  30. package/handlers/organizations.js +14 -0
  31. package/handlers/projects.js +122 -0
  32. package/handlers/recurring-tasks.js +33 -0
  33. package/handlers/tags.js +124 -0
  34. package/handlers/tasks.js +561 -0
  35. package/handlers/testing.js +116 -0
  36. package/handlers/todos.js +43 -0
  37. package/handlers/watchers.js +54 -0
  38. package/handlers/work-templates.js +32 -0
  39. package/index.js +175 -0
  40. package/lib/active-session.js +86 -0
  41. package/lib/auto-assign.js +93 -0
  42. package/lib/autolink.js +176 -0
  43. package/lib/changed-files.js +22 -0
  44. package/lib/env.js +45 -0
  45. package/lib/git-helpers.js +553 -0
  46. package/lib/git-utils.js +73 -0
  47. package/lib/http-client.js +164 -0
  48. package/lib/links-at-create.js +94 -0
  49. package/lib/local-cache.js +140 -0
  50. package/lib/logger.js +109 -0
  51. package/lib/manifest-loader.js +182 -0
  52. package/lib/manifest-query.js +686 -0
  53. package/lib/repo-config-dir.js +118 -0
  54. package/lib/version.js +10 -0
  55. package/lib/web-url.js +69 -0
  56. package/lib/worktree-tools.js +950 -0
  57. package/package.json +62 -0
  58. package/prompts/ai-workflow-automation.js +96 -0
  59. package/prompts/index.js +39 -0
  60. package/prompts/zephly-usage-guide-content.txt +631 -0
  61. package/prompts/zephly-usage-guide.js +119 -0
  62. package/tools/access-entity-types.js +28 -0
  63. package/tools/access.js +152 -0
  64. package/tools/activity.js +38 -0
  65. package/tools/agents.js +208 -0
  66. package/tools/ai-intelligence.js +111 -0
  67. package/tools/attachments.js +92 -0
  68. package/tools/catalogs.js +341 -0
  69. package/tools/components.js +249 -0
  70. package/tools/context-manifest.js +236 -0
  71. package/tools/decisions.js +168 -0
  72. package/tools/designs.js +222 -0
  73. package/tools/documents.js +287 -0
  74. package/tools/entities.js +223 -0
  75. package/tools/epics.js +267 -0
  76. package/tools/facts.js +70 -0
  77. package/tools/feature-flags.js +300 -0
  78. package/tools/features.js +246 -0
  79. package/tools/folders.js +122 -0
  80. package/tools/git-context.js +109 -0
  81. package/tools/github.js +172 -0
  82. package/tools/graph.js +70 -0
  83. package/tools/index.js +77 -0
  84. package/tools/link-params.js +93 -0
  85. package/tools/linkable-types.js +36 -0
  86. package/tools/links.js +199 -0
  87. package/tools/milestones.js +176 -0
  88. package/tools/organizations.js +23 -0
  89. package/tools/projects.js +172 -0
  90. package/tools/recurring-tasks.js +115 -0
  91. package/tools/tags.js +219 -0
  92. package/tools/task-item-schema.js +57 -0
  93. package/tools/task-type.js +33 -0
  94. package/tools/tasks.js +680 -0
  95. package/tools/testing.js +344 -0
  96. package/tools/todos.js +69 -0
  97. package/tools/watchers.js +81 -0
  98. package/tools/work-templates.js +96 -0
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Entity Management Tools
3
+ * MCP tools for managing goals, teams, and labels
4
+ *
5
+ * Consolidated: manage_goal (create/update/delete), manage_team (create), get_goal (get/list)
6
+ */
7
+
8
+ export const ENTITY_TOOLS = [
9
+ {
10
+ name: 'manage_goal',
11
+ description: 'Create, update, or delete organization-wide strategic goals, or ' +
12
+ '(re)generate a goal\'s grounded "how it works" living description.',
13
+ inputSchema: {
14
+ type: 'object',
15
+ properties: {
16
+ action: {
17
+ type: 'string',
18
+ enum: ['create', 'update', 'delete', 'generate_how_it_works', 'apply_how_it_works'],
19
+ description: 'Action to perform. "generate_how_it_works" (re)generates the ' +
20
+ 'goal\'s grounded, source-attributed "how it works" living description from ' +
21
+ 'its linked work (requires goalId; AI-quota gated). "apply_how_it_works" (BYO-AI) ' +
22
+ 'persists a summary YOU authored (markdown + sources); the server validates your cited ' +
23
+ 'sources against the real grounded context before saving — no server model call. Read ' +
24
+ 'the result back via get_goal.',
25
+ },
26
+ // --- Identifiers ---
27
+ goalId: {
28
+ type: 'string',
29
+ description: 'Goal ID (required for update, delete, generate_how_it_works, apply_how_it_works)',
30
+ },
31
+ // --- apply_how_it_works (BYO-AI) ---
32
+ markdown: {
33
+ type: 'string',
34
+ description: 'Rendered markdown body for apply_how_it_works (the how-it-works YOU authored).',
35
+ },
36
+ sources: {
37
+ type: 'object',
38
+ description: 'Structured backing for apply_how_it_works: { claims: [{ text, sources: [ref...], ' +
39
+ 'confidence: "grounded"|"unverified" }], divergences: [{ intent, reality, severity }] }. Cite ' +
40
+ 'real source refs from the goal\'s grounded context; the server drops fabricated ones.',
41
+ },
42
+ organizationId: {
43
+ type: 'string',
44
+ description: 'Organization ID (required for create)',
45
+ },
46
+ // --- Create fields ---
47
+ title: {
48
+ type: 'string',
49
+ description: 'Goal title (required for create, optional for update)',
50
+ },
51
+ description: {
52
+ type: 'string',
53
+ description: 'Goal description — supports markdown. Used by create and update.',
54
+ },
55
+ targetDate: {
56
+ type: 'string',
57
+ description: 'Target completion date (RFC3339 format, e.g., 2026-03-31T00:00:00Z). Used by create and update.',
58
+ },
59
+ status: {
60
+ type: 'string',
61
+ enum: ['active', 'completed', 'archived'],
62
+ description: 'Goal status (default: active). Used by create and update.',
63
+ },
64
+ parentGoalId: {
65
+ type: 'string',
66
+ description: 'Parent goal ID for goal hierarchy (create only)',
67
+ },
68
+ metrics: {
69
+ type: 'array',
70
+ description: 'Goal metrics. Used by create and update.',
71
+ items: {
72
+ type: 'object',
73
+ properties: {
74
+ id: { type: 'string' },
75
+ name: { type: 'string' },
76
+ target: { type: 'number' },
77
+ unit: { type: 'string' },
78
+ current: { type: 'number' },
79
+ description: { type: 'string' },
80
+ },
81
+ required: ['name', 'target', 'unit'],
82
+ },
83
+ },
84
+ linkedMilestones: {
85
+ type: 'array',
86
+ description: 'Milestones to link to this goal. Used by create and update.',
87
+ items: {
88
+ type: 'object',
89
+ properties: {
90
+ projectId: { type: 'string', description: 'Project ID containing the milestone' },
91
+ milestoneId: { type: 'string', description: 'Milestone ID to link' },
92
+ },
93
+ required: ['projectId', 'milestoneId'],
94
+ },
95
+ },
96
+ epicIds: {
97
+ type: 'array',
98
+ items: { type: 'string' },
99
+ description: 'Array of linked epic IDs (update only)',
100
+ },
101
+ labels: {
102
+ type: 'array',
103
+ items: { type: 'string' },
104
+ description: 'Array of label IDs. Used by create and update.',
105
+ },
106
+ teamIds: {
107
+ type: 'array',
108
+ items: { type: 'string' },
109
+ description: 'Array of team IDs responsible for this goal. Used by create and update.',
110
+ },
111
+ },
112
+ required: ['action'],
113
+ },
114
+ },
115
+ {
116
+ name: 'manage_team',
117
+ description: 'Create a team within an organization.',
118
+ inputSchema: {
119
+ type: 'object',
120
+ properties: {
121
+ action: {
122
+ type: 'string',
123
+ enum: ['create'],
124
+ description: 'Action to perform',
125
+ },
126
+ organizationId: {
127
+ type: 'string',
128
+ description: 'Organization ID (required for create)',
129
+ },
130
+ name: {
131
+ type: 'string',
132
+ description: 'Team name (required for create)',
133
+ },
134
+ description: {
135
+ type: 'string',
136
+ description: 'Team description',
137
+ },
138
+ memberIds: {
139
+ type: 'array',
140
+ items: { type: 'string' },
141
+ description: 'Array of user IDs to add as team members',
142
+ },
143
+ slug: {
144
+ type: 'string',
145
+ description: 'URL-friendly slug (e.g., "frontend-team")',
146
+ },
147
+ color: {
148
+ type: 'string',
149
+ description: 'Hex color for visual identification (e.g., "#3B82F6")',
150
+ },
151
+ leaderId: {
152
+ type: 'string',
153
+ description: 'User ID of team lead/manager',
154
+ },
155
+ sprintOverride: {
156
+ type: 'object',
157
+ description: 'Sprint configuration override',
158
+ properties: {
159
+ enabled: { type: 'boolean' },
160
+ duration: { type: 'number', enum: [7, 10, 14, 21] },
161
+ startDate: { type: 'string', description: 'RFC3339 format (e.g., 2026-01-01T00:00:00Z)' },
162
+ offset: { type: 'number', description: 'Days offset from org sprint' },
163
+ },
164
+ },
165
+ capacityOverrides: {
166
+ type: 'array',
167
+ description: 'Individual capacity overrides per member',
168
+ items: {
169
+ type: 'object',
170
+ properties: {
171
+ memberId: { type: 'string' },
172
+ pointsPerSprint: { type: 'number' },
173
+ },
174
+ },
175
+ },
176
+ },
177
+ required: ['action'],
178
+ },
179
+ },
180
+ {
181
+ name: 'get_goal',
182
+ description: 'Retrieve a single goal or list all goals. ' +
183
+ 'Modes: (1) Provide goalId for single lookup. ' +
184
+ '(2) Provide organizationId + goalNumber for number lookup. ' +
185
+ '(3) Provide organizationId to list all goals with optional filters.',
186
+ inputSchema: {
187
+ type: 'object',
188
+ properties: {
189
+ // --- Single goal lookup ---
190
+ goalId: {
191
+ type: 'string',
192
+ description: 'Document ID of the goal to retrieve',
193
+ },
194
+ organizationId: {
195
+ type: 'string',
196
+ description: 'Organization ID (required for goalNumber lookup or listing)',
197
+ },
198
+ goalNumber: {
199
+ type: 'number',
200
+ description: 'Sequential goal number (e.g., 7 for goal g-7). Must be used with organizationId.',
201
+ },
202
+ includeEpics: {
203
+ type: 'boolean',
204
+ description: 'Include linked epic details (single goal mode)',
205
+ },
206
+ // --- List filters ---
207
+ status: {
208
+ type: 'string',
209
+ enum: ['active', 'completed', 'archived'],
210
+ description: 'Filter by goal status (list mode)',
211
+ },
212
+ teamId: {
213
+ type: 'string',
214
+ description: 'Filter by team assignment (list mode)',
215
+ },
216
+ limit: {
217
+ type: 'number',
218
+ description: 'Maximum number of results (list mode, default: 50)',
219
+ },
220
+ },
221
+ },
222
+ },
223
+ ];
package/tools/epics.js ADDED
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Epic Tools
3
+ * MCP tools for managing epics
4
+ *
5
+ * Project-First Hierarchy: Epics belong to projects (required),
6
+ * with optional component grouping and milestone linking. *
7
+ * NAMING (E-107): an epic is not called "Epic" everywhere. A project's type
8
+ * decides its vocabulary — a marketing project calls this a Campaign, a sales
9
+ * project a Deal, a research project a Study. Read the words from
10
+ * `get_current_project_context().terminology` (or `get_project`) and use them in
11
+ * anything a person reads. The field names here — epicId, epicNumber — never
12
+ * change.
13
+ */
14
+
15
+ import { LINKS_ARRAY_SCHEMA, RELATED_ITEM_SCHEMA } from './link-params.js';
16
+ import { TASK_ITEM_PROPERTIES } from './task-item-schema.js';
17
+
18
+ export const EPIC_TOOLS = [
19
+ {
20
+ name: 'manage_epic',
21
+ description: 'Create or update an epic within a project. Epics belong to projects (required). ' +
22
+ 'IMPORTANT when creating: Call get_context first for each area the epic covers to discover relevant ' +
23
+ 'files and integration points. Include in the description which layers/services are affected and ' +
24
+ 'reference specific file paths. Create child tasks that each reference specific files from context queries. ' +
25
+ 'Auto-applies matching tags from cached project context based on content analysis. ' +
26
+ 'To align an epic to an organization goal, link it to a milestone that is linked to that goal ' +
27
+ '(set milestoneId) — epics have no direct goal field. ' +
28
+ 'BREAKING DOWN A FEATURE: pass the child tasks in the `tasks` array on create and the epic and its ' +
29
+ 'whole breakdown are created in ONE request — do not follow a create with a separate create_tasks call. ' +
30
+ 'Besides the saved request, it removes the gap between the two: a failure part-way can no longer ' +
31
+ 'leave an epic with no tasks that you then have to reconcile.',
32
+ inputSchema: {
33
+ type: 'object',
34
+ properties: {
35
+ action: {
36
+ type: 'string',
37
+ enum: ['create', 'update', 'generate_how_it_works', 'apply_how_it_works'],
38
+ description: 'Action to perform. "generate_how_it_works" (re)generates the epic\'s grounded, ' +
39
+ 'source-attributed "how it works" living description from its reality — its tasks\' status ' +
40
+ 'rollup, their captured decisions and their linked commits (requires epicId; AI-quota gated). ' +
41
+ 'An epic is where intent and reality drift furthest apart: intent is a charter written once, ' +
42
+ 'reality is months of accumulated work. "apply_how_it_works" (BYO-AI) persists a summary YOU ' +
43
+ 'authored: pass markdown + sources; the server validates your cited sources against the real ' +
44
+ 'grounded context (dropping fabricated ones) before saving — no server model call.',
45
+ },
46
+ // --- Identifiers ---
47
+ epicId: {
48
+ type: 'string',
49
+ description: 'Epic ID (required for update, generate_how_it_works, apply_how_it_works)',
50
+ },
51
+ markdown: {
52
+ type: 'string',
53
+ description: 'Rendered markdown body for apply_how_it_works (the how-it-works YOU authored).',
54
+ },
55
+ sources: {
56
+ type: 'object',
57
+ description: 'Structured backing for apply_how_it_works: { claims: [{ text, sources: [ref...], ' +
58
+ 'confidence }], divergences: [{ intent, reality, severity }] }. Cite real source refs from the ' +
59
+ 'epic\'s grounded context ("task:<id>", "commit:<sha>", "epic:<id>"); the server drops ' +
60
+ 'fabricated ones.',
61
+ },
62
+ projectId: {
63
+ type: 'string',
64
+ description: 'Project ID (required for create)',
65
+ },
66
+ // --- Shared fields ---
67
+ title: {
68
+ type: 'string',
69
+ description: 'Epic title (required for create)',
70
+ },
71
+ description: {
72
+ type: 'string',
73
+ description: 'Epic description (supports markdown). Use real newlines, not literal \\n. ' +
74
+ 'Writing this stays plain text; it does not create a backing document.',
75
+ },
76
+ status: {
77
+ type: 'string',
78
+ enum: ['backlog', 'ready', 'active', 'completed', 'cancelled', 'archived'],
79
+ description: 'Epic status (default: backlog for create)',
80
+ },
81
+ milestoneId: {
82
+ type: 'string',
83
+ description: 'Link to project milestone (set to empty string to remove on update). ' +
84
+ 'This is also how an epic aligns to an organization goal: link the epic to a ' +
85
+ 'milestone that is linked to the goal — there is no direct goal field on an epic.',
86
+ },
87
+ featureId: {
88
+ type: 'string',
89
+ description: 'Tie this epic to a durable Feature it advances (E-210). When the project ' +
90
+ 'has feature-link governance enabled, this is REQUIRED on create (and on updating an ' +
91
+ 'unlinked epic): the epic is linked to the feature via a relates_to edge. If a create/update ' +
92
+ 'is rejected with "requires every epic to be linked to a Feature", find an existing ' +
93
+ 'capability or propose a new one with search_features, then pass its id here.',
94
+ },
95
+ startDate: {
96
+ type: 'string',
97
+ description: 'Start date (RFC3339 format, e.g., 2026-01-01T00:00:00Z)',
98
+ },
99
+ endDate: {
100
+ type: 'string',
101
+ description: 'End/deadline date (RFC3339 format). Enforced — incomplete tasks auto-move to backlog when passed.',
102
+ },
103
+ estimatedHours: {
104
+ type: 'number',
105
+ description: 'Epic-level effort estimate in HOURS. Stored as given — the API does not ' +
106
+ 'derive dates from it (the web rail does that client-side, at 8h per work day). Distinct ' +
107
+ 'from the points shown on the epic detail, which are a read-only rollup of the child ' +
108
+ 'tasks\' sprintPoints: this is the epic\'s own input, that is what the tasks add up to.',
109
+ },
110
+ owner: {
111
+ type: 'object',
112
+ description: 'Epic owner (userId and name)',
113
+ properties: {
114
+ userId: { type: 'string' },
115
+ name: { type: 'string' },
116
+ },
117
+ },
118
+ labels: {
119
+ type: 'array',
120
+ items: { type: 'string' },
121
+ description: 'Array of label names',
122
+ },
123
+ color: {
124
+ type: 'string',
125
+ description: 'Hex color for visual identification (e.g., "#3B82F6"). Set to empty string to remove on update.',
126
+ },
127
+ links: LINKS_ARRAY_SCHEMA,
128
+ // --- Create-only: the epic's breakdown, created in the same request ---
129
+ componentId: {
130
+ type: 'string',
131
+ description: 'Component applied to every task in `tasks` that does not set its own ' +
132
+ '(create only). Get available components from get_current_project_context().',
133
+ },
134
+ tasks: {
135
+ type: 'array',
136
+ description: 'Child tasks to create WITH the epic, in the same request (create only, 1-40). ' +
137
+ 'Each item takes the same fields as manage_task action:"create"; only title is required. ' +
138
+ 'projectId and epicId are taken from the epic — do not set them per item. ' +
139
+ 'The response reports the epic separately from a per-item task result: if some tasks fail, ' +
140
+ 'the epic still exists and you retry ONLY the failed items, never the whole call. ' +
141
+ 'For more than 40 tasks, create the epic here with the first 40 and send the rest with create_tasks.',
142
+ items: {
143
+ type: 'object',
144
+ properties: { ...TASK_ITEM_PROPERTIES },
145
+ required: ['title'],
146
+ },
147
+ },
148
+ // --- Update-only fields ---
149
+ addLinks: {
150
+ type: 'array',
151
+ items: LINKS_ARRAY_SCHEMA.items,
152
+ description: 'Add cross-entity links to an existing epic (update only). ' +
153
+ 'Same shape as `links` on create.',
154
+ },
155
+ removeLinks: {
156
+ type: 'array',
157
+ items: LINKS_ARRAY_SCHEMA.items,
158
+ description: 'Remove cross-entity links from an existing epic (update only).',
159
+ },
160
+ addRelatedItem: {
161
+ ...RELATED_ITEM_SCHEMA,
162
+ description: 'DEPRECATED — use addLinks. Add a cross-entity related item ' +
163
+ 'link (update only). Still works; addLinks takes several at once and ' +
164
+ 'supports linkType.',
165
+ },
166
+ removeRelatedItem: {
167
+ ...RELATED_ITEM_SCHEMA,
168
+ description: 'DEPRECATED — use removeLinks. Remove a cross-entity related ' +
169
+ 'item link (update only). Still works.',
170
+ },
171
+ addDependency: {
172
+ type: 'string',
173
+ description: 'Add a cross-project blocking dependency by epic ID. ' +
174
+ 'Same-org only. Rejected as ErrCircularDependency if it would close a cycle. (update only)',
175
+ },
176
+ removeDependency: {
177
+ type: 'string',
178
+ description: 'Remove a blocking dependency by target epic ID. ' +
179
+ 'Idempotent — no error if absent. (update only)',
180
+ },
181
+ },
182
+ required: ['action'],
183
+ },
184
+ },
185
+ {
186
+ name: 'search_epics',
187
+ description: 'Search and filter epics by project, status, or text. ' +
188
+ 'Primary filter is by project. If no scope (projectId) is provided, ' +
189
+ 'searches across all projects accessible to the API key. ' +
190
+ 'To find epics aligned to a goal, filter by the goal\'s milestone (milestoneId).',
191
+ inputSchema: {
192
+ type: 'object',
193
+ properties: {
194
+ projectId: {
195
+ type: 'string',
196
+ description: 'Filter by project ID (primary filter)',
197
+ },
198
+ milestoneId: {
199
+ type: 'string',
200
+ description: 'Filter by milestone ID (release)',
201
+ },
202
+ status: {
203
+ type: 'string',
204
+ enum: ['backlog', 'ready', 'active', 'completed', 'cancelled', 'archived'],
205
+ description: 'Filter by epic status',
206
+ },
207
+ searchText: {
208
+ type: 'string',
209
+ description: 'Text to search in epic title or description (case-insensitive)',
210
+ },
211
+ limit: {
212
+ type: 'number',
213
+ description: 'Maximum number of results (default: 50, max: 1000)',
214
+ default: 50,
215
+ },
216
+ },
217
+ },
218
+ },
219
+ {
220
+ name: 'list_epics',
221
+ description: 'List all epics for a specific project. For advanced filtering use search_epics. Requires projectId.',
222
+ inputSchema: {
223
+ type: 'object',
224
+ properties: {
225
+ projectId: {
226
+ type: 'string',
227
+ description: 'The ID of the project to list epics for (required)',
228
+ },
229
+ },
230
+ },
231
+ },
232
+ {
233
+ name: 'get_epic',
234
+ description: 'Retrieve a single epic by ID or epic number with ' +
235
+ 'full details. Provide EITHER epicId OR both epicNumber and projectId. ' +
236
+ 'Optionally include lightweight task information ' +
237
+ '(id, title, status, priority, assignee). ' +
238
+ 'Responses include `descriptionDocumentId` — the id of the backing rich-description Document ' +
239
+ 'when the description has been promoted to one (E-189), otherwise omitted. ' +
240
+ 'Responses also include `derivedGoalIds` — the organization goal(s) this epic aligns to, ' +
241
+ 'derived via its milestone (epics have no direct goal field).',
242
+ inputSchema: {
243
+ type: 'object',
244
+ properties: {
245
+ epicId: {
246
+ type: 'string',
247
+ description: 'The document ID of the epic to retrieve',
248
+ },
249
+ epicNumber: {
250
+ type: 'number',
251
+ description: 'The sequential epic number (e.g., 7 for ' +
252
+ 'epic #7). Must be used with projectId. This is the ' +
253
+ 'human-friendly number displayed in the UI.',
254
+ },
255
+ projectId: {
256
+ type: 'string',
257
+ description: 'The project ID. Required when using epicNumber instead of epicId.',
258
+ },
259
+ includeTasks: {
260
+ type: 'boolean',
261
+ description: 'If true, includes lightweight task info (id, title, status, priority, assignee) ' +
262
+ 'for all tasks in this epic. This is the recommended way to get all tasks in an epic.',
263
+ },
264
+ },
265
+ },
266
+ },
267
+ ];
package/tools/facts.js ADDED
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Fact Tools
3
+ * MCP tools for managing project-scoped facts (knowledge entries)
4
+ *
5
+ * Facts are short, tagged knowledge items scoped to a project — useful for
6
+ * capturing decisions, conventions, and reference info that humans and AI
7
+ * agents need.
8
+ */
9
+
10
+ export const FACT_TOOLS = [
11
+ {
12
+ name: 'manage_fact',
13
+ description: 'Create, update, or delete project facts (knowledge entries). ' +
14
+ 'Facts are short, tagged knowledge items scoped to a project — useful for capturing decisions, conventions, and reference info that humans and AI agents need.',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ action: {
19
+ type: 'string',
20
+ enum: ['create', 'update', 'delete'],
21
+ description: 'Action to perform',
22
+ },
23
+ projectId: {
24
+ type: 'string',
25
+ description: 'Project ID (required for create and delete)',
26
+ },
27
+ factId: {
28
+ type: 'string',
29
+ description: 'Fact ID (required for update and delete)',
30
+ },
31
+ title: {
32
+ type: 'string',
33
+ description: 'Fact title (required for create)',
34
+ },
35
+ content: {
36
+ type: 'string',
37
+ description: 'Fact content (supports markdown)',
38
+ },
39
+ pinned: {
40
+ type: 'boolean',
41
+ description: 'Pin fact to top of list',
42
+ },
43
+ tagIds: {
44
+ type: 'array',
45
+ items: { type: 'string' },
46
+ description: 'Tag IDs for categorization',
47
+ },
48
+ },
49
+ required: ['action'],
50
+ },
51
+ },
52
+ {
53
+ name: 'list_facts',
54
+ description: 'List all project facts (knowledge entries) for a project. Returns pinned facts first.',
55
+ inputSchema: {
56
+ type: 'object',
57
+ properties: {
58
+ projectId: {
59
+ type: 'string',
60
+ description: 'Project ID (required)',
61
+ },
62
+ factId: {
63
+ type: 'string',
64
+ description: 'Optional: get a single fact by ID instead of listing all',
65
+ },
66
+ },
67
+ required: ['projectId'],
68
+ },
69
+ },
70
+ ];