@pollychrome/joan-mcp 1.0.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 (83) hide show
  1. package/README.md +385 -0
  2. package/bin/joan-mcp +16 -0
  3. package/dist/auth.d.ts +49 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +264 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/cli.d.ts +7 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +326 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/client/api-client.d.ts +86 -0
  12. package/dist/client/api-client.d.ts.map +1 -0
  13. package/dist/client/api-client.js +182 -0
  14. package/dist/client/api-client.js.map +1 -0
  15. package/dist/client/types.d.ts +270 -0
  16. package/dist/client/types.d.ts.map +1 -0
  17. package/dist/client/types.js +5 -0
  18. package/dist/client/types.js.map +1 -0
  19. package/dist/config.d.ts +33 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +71 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/index.d.ts +14 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +118 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/resources/goals.d.ts +7 -0
  28. package/dist/resources/goals.d.ts.map +1 -0
  29. package/dist/resources/goals.js +49 -0
  30. package/dist/resources/goals.js.map +1 -0
  31. package/dist/resources/index.d.ts +16 -0
  32. package/dist/resources/index.d.ts.map +1 -0
  33. package/dist/resources/index.js +20 -0
  34. package/dist/resources/index.js.map +1 -0
  35. package/dist/resources/milestones.d.ts +7 -0
  36. package/dist/resources/milestones.d.ts.map +1 -0
  37. package/dist/resources/milestones.js +40 -0
  38. package/dist/resources/milestones.js.map +1 -0
  39. package/dist/resources/notes.d.ts +7 -0
  40. package/dist/resources/notes.d.ts.map +1 -0
  41. package/dist/resources/notes.js +33 -0
  42. package/dist/resources/notes.js.map +1 -0
  43. package/dist/resources/projects.d.ts +7 -0
  44. package/dist/resources/projects.d.ts.map +1 -0
  45. package/dist/resources/projects.js +97 -0
  46. package/dist/resources/projects.js.map +1 -0
  47. package/dist/resources/tasks.d.ts +7 -0
  48. package/dist/resources/tasks.d.ts.map +1 -0
  49. package/dist/resources/tasks.js +36 -0
  50. package/dist/resources/tasks.js.map +1 -0
  51. package/dist/tools/goals.d.ts +7 -0
  52. package/dist/tools/goals.d.ts.map +1 -0
  53. package/dist/tools/goals.js +114 -0
  54. package/dist/tools/goals.js.map +1 -0
  55. package/dist/tools/index.d.ts +16 -0
  56. package/dist/tools/index.d.ts.map +1 -0
  57. package/dist/tools/index.js +20 -0
  58. package/dist/tools/index.js.map +1 -0
  59. package/dist/tools/milestones.d.ts +7 -0
  60. package/dist/tools/milestones.d.ts.map +1 -0
  61. package/dist/tools/milestones.js +119 -0
  62. package/dist/tools/milestones.js.map +1 -0
  63. package/dist/tools/notes.d.ts +7 -0
  64. package/dist/tools/notes.d.ts.map +1 -0
  65. package/dist/tools/notes.js +82 -0
  66. package/dist/tools/notes.js.map +1 -0
  67. package/dist/tools/projects.d.ts +7 -0
  68. package/dist/tools/projects.d.ts.map +1 -0
  69. package/dist/tools/projects.js +63 -0
  70. package/dist/tools/projects.js.map +1 -0
  71. package/dist/tools/tasks.d.ts +7 -0
  72. package/dist/tools/tasks.d.ts.map +1 -0
  73. package/dist/tools/tasks.js +125 -0
  74. package/dist/tools/tasks.js.map +1 -0
  75. package/dist/utils/converters.d.ts +78 -0
  76. package/dist/utils/converters.d.ts.map +1 -0
  77. package/dist/utils/converters.js +79 -0
  78. package/dist/utils/converters.js.map +1 -0
  79. package/dist/utils/errors.d.ts +27 -0
  80. package/dist/utils/errors.d.ts.map +1 -0
  81. package/dist/utils/errors.js +104 -0
  82. package/dist/utils/errors.js.map +1 -0
  83. package/package.json +53 -0
@@ -0,0 +1,114 @@
1
+ /**
2
+ * MCP tools for goal management
3
+ */
4
+ import { z } from 'zod';
5
+ import { formatErrorForMcp } from '../utils/errors.js';
6
+ export function registerGoalTools(server, client) {
7
+ // Create Goal
8
+ server.tool('create_goal', 'Create a new goal in Joan.', {
9
+ title: z.string().min(1).describe('Goal title'),
10
+ description: z.string().optional().describe('Goal description'),
11
+ type: z.enum(['daily', 'weekly', 'monthly', 'yearly', 'standard']).optional().describe('Goal type'),
12
+ target_date: z.string().optional().describe('Target date (ISO 8601 format)'),
13
+ }, async (input) => {
14
+ try {
15
+ const goal = await client.createGoal({
16
+ title: input.title,
17
+ description: input.description,
18
+ type: input.type,
19
+ target_date: input.target_date,
20
+ });
21
+ return {
22
+ content: [{
23
+ type: 'text',
24
+ text: `Created goal "${goal.title}" (ID: ${goal.id})`,
25
+ }],
26
+ };
27
+ }
28
+ catch (error) {
29
+ return { content: formatErrorForMcp(error) };
30
+ }
31
+ });
32
+ // Update Goal
33
+ server.tool('update_goal', 'Update an existing goal in Joan.', {
34
+ goal_id: z.string().uuid().describe('Goal ID to update'),
35
+ title: z.string().min(1).optional().describe('New goal title'),
36
+ description: z.string().optional().describe('New goal description'),
37
+ status: z.enum(['active', 'paused', 'completed', 'archived']).optional().describe('New goal status'),
38
+ target_date: z.string().optional().describe('New target date (ISO 8601 format)'),
39
+ progress: z.number().int().min(0).max(100).optional().describe('Progress percentage (0-100)'),
40
+ }, async (input) => {
41
+ try {
42
+ const goal = await client.updateGoal(input.goal_id, {
43
+ title: input.title,
44
+ description: input.description,
45
+ status: input.status,
46
+ target_date: input.target_date,
47
+ progress: input.progress,
48
+ });
49
+ return {
50
+ content: [{
51
+ type: 'text',
52
+ text: `Updated goal "${goal.title}" (ID: ${goal.id})`,
53
+ }],
54
+ };
55
+ }
56
+ catch (error) {
57
+ return { content: formatErrorForMcp(error) };
58
+ }
59
+ });
60
+ // Delete Goal
61
+ server.tool('delete_goal', 'Delete a goal from Joan.', {
62
+ goal_id: z.string().uuid().describe('Goal ID to delete'),
63
+ }, async (input) => {
64
+ try {
65
+ await client.deleteGoal(input.goal_id);
66
+ return {
67
+ content: [{
68
+ type: 'text',
69
+ text: `Goal ${input.goal_id} deleted`,
70
+ }],
71
+ };
72
+ }
73
+ catch (error) {
74
+ return { content: formatErrorForMcp(error) };
75
+ }
76
+ });
77
+ // Link Task to Goal
78
+ server.tool('link_task_to_goal', 'Link a task to a goal to track progress.', {
79
+ goal_id: z.string().uuid().describe('Goal ID'),
80
+ task_id: z.string().uuid().describe('Task ID to link'),
81
+ }, async (input) => {
82
+ try {
83
+ await client.linkTaskToGoal(input.goal_id, input.task_id);
84
+ return {
85
+ content: [{
86
+ type: 'text',
87
+ text: `Linked task ${input.task_id} to goal ${input.goal_id}`,
88
+ }],
89
+ };
90
+ }
91
+ catch (error) {
92
+ return { content: formatErrorForMcp(error) };
93
+ }
94
+ });
95
+ // Unlink Task from Goal
96
+ server.tool('unlink_task_from_goal', 'Remove a task from a goal.', {
97
+ goal_id: z.string().uuid().describe('Goal ID'),
98
+ task_id: z.string().uuid().describe('Task ID to unlink'),
99
+ }, async (input) => {
100
+ try {
101
+ await client.unlinkTaskFromGoal(input.goal_id, input.task_id);
102
+ return {
103
+ content: [{
104
+ type: 'text',
105
+ text: `Unlinked task ${input.task_id} from goal ${input.goal_id}`,
106
+ }],
107
+ };
108
+ }
109
+ catch (error) {
110
+ return { content: formatErrorForMcp(error) };
111
+ }
112
+ });
113
+ }
114
+ //# sourceMappingURL=goals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goals.js","sourceRoot":"","sources":["../../src/tools/goals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Tool registration for Joan MCP server
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { JoanApiClient } from '../client/api-client.js';
6
+ import { registerTaskTools } from './tasks.js';
7
+ import { registerProjectTools } from './projects.js';
8
+ import { registerMilestoneTools } from './milestones.js';
9
+ import { registerGoalTools } from './goals.js';
10
+ import { registerNoteTools } from './notes.js';
11
+ /**
12
+ * Register all tools with the MCP server
13
+ */
14
+ export declare function registerAllTools(server: McpServer, client: JoanApiClient): void;
15
+ export { registerTaskTools, registerProjectTools, registerMilestoneTools, registerGoalTools, registerNoteTools, };
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAM/E;AAED,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,GAClB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Tool registration for Joan MCP server
3
+ */
4
+ import { registerTaskTools } from './tasks.js';
5
+ import { registerProjectTools } from './projects.js';
6
+ import { registerMilestoneTools } from './milestones.js';
7
+ import { registerGoalTools } from './goals.js';
8
+ import { registerNoteTools } from './notes.js';
9
+ /**
10
+ * Register all tools with the MCP server
11
+ */
12
+ export function registerAllTools(server, client) {
13
+ registerTaskTools(server, client);
14
+ registerProjectTools(server, client);
15
+ registerMilestoneTools(server, client);
16
+ registerGoalTools(server, client);
17
+ registerNoteTools(server, client);
18
+ }
19
+ export { registerTaskTools, registerProjectTools, registerMilestoneTools, registerGoalTools, registerNoteTools, };
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAqB;IACvE,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,GAClB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP tools for milestone management
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { JoanApiClient } from '../client/api-client.js';
6
+ export declare function registerMilestoneTools(server: McpServer, client: JoanApiClient): void;
7
+ //# sourceMappingURL=milestones.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"milestones.d.ts","sourceRoot":"","sources":["../../src/tools/milestones.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA6IrF"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * MCP tools for milestone management
3
+ */
4
+ import { z } from 'zod';
5
+ import { formatErrorForMcp } from '../utils/errors.js';
6
+ export function registerMilestoneTools(server, client) {
7
+ // Create Milestone
8
+ server.tool('create_milestone', 'Create a new milestone in a Joan project.', {
9
+ project_id: z.string().uuid().describe('Project ID to create milestone in'),
10
+ name: z.string().min(1).describe('Milestone name'),
11
+ description: z.string().optional().describe('Milestone description'),
12
+ target_date: z.string().optional().describe('Target completion date (ISO 8601 format)'),
13
+ status: z.enum(['upcoming', 'in_progress', 'completed', 'missed']).optional().describe('Milestone status'),
14
+ }, async (input) => {
15
+ try {
16
+ const milestone = await client.createMilestone(input.project_id, {
17
+ name: input.name,
18
+ description: input.description,
19
+ target_date: input.target_date,
20
+ status: input.status,
21
+ });
22
+ return {
23
+ content: [{
24
+ type: 'text',
25
+ text: `Created milestone "${milestone.name}" (ID: ${milestone.id}) in project ${input.project_id}`,
26
+ }],
27
+ };
28
+ }
29
+ catch (error) {
30
+ return { content: formatErrorForMcp(error) };
31
+ }
32
+ });
33
+ // Update Milestone
34
+ server.tool('update_milestone', 'Update an existing milestone in a Joan project.', {
35
+ project_id: z.string().uuid().describe('Project ID'),
36
+ milestone_id: z.string().uuid().describe('Milestone ID to update'),
37
+ name: z.string().min(1).optional().describe('New milestone name'),
38
+ description: z.string().optional().describe('New milestone description'),
39
+ target_date: z.string().optional().describe('New target date (ISO 8601 format)'),
40
+ status: z.enum(['upcoming', 'in_progress', 'completed', 'missed']).optional().describe('New milestone status'),
41
+ progress: z.number().int().min(0).max(100).optional().describe('Progress percentage (0-100)'),
42
+ }, async (input) => {
43
+ try {
44
+ const milestone = await client.updateMilestone(input.project_id, input.milestone_id, {
45
+ name: input.name,
46
+ description: input.description,
47
+ target_date: input.target_date,
48
+ status: input.status,
49
+ progress: input.progress,
50
+ });
51
+ return {
52
+ content: [{
53
+ type: 'text',
54
+ text: `Updated milestone "${milestone.name}" (ID: ${milestone.id})`,
55
+ }],
56
+ };
57
+ }
58
+ catch (error) {
59
+ return { content: formatErrorForMcp(error) };
60
+ }
61
+ });
62
+ // Delete Milestone
63
+ server.tool('delete_milestone', 'Delete a milestone from a Joan project.', {
64
+ project_id: z.string().uuid().describe('Project ID'),
65
+ milestone_id: z.string().uuid().describe('Milestone ID to delete'),
66
+ }, async (input) => {
67
+ try {
68
+ await client.deleteMilestone(input.project_id, input.milestone_id);
69
+ return {
70
+ content: [{
71
+ type: 'text',
72
+ text: `Milestone ${input.milestone_id} deleted from project ${input.project_id}`,
73
+ }],
74
+ };
75
+ }
76
+ catch (error) {
77
+ return { content: formatErrorForMcp(error) };
78
+ }
79
+ });
80
+ // Link Tasks to Milestone
81
+ server.tool('link_tasks_to_milestone', 'Link one or more tasks to a milestone.', {
82
+ project_id: z.string().uuid().describe('Project ID'),
83
+ milestone_id: z.string().uuid().describe('Milestone ID'),
84
+ task_ids: z.array(z.string().uuid()).min(1).describe('Array of task IDs to link'),
85
+ }, async (input) => {
86
+ try {
87
+ await client.linkTasksToMilestone(input.project_id, input.milestone_id, input.task_ids);
88
+ return {
89
+ content: [{
90
+ type: 'text',
91
+ text: `Linked ${input.task_ids.length} task(s) to milestone ${input.milestone_id}`,
92
+ }],
93
+ };
94
+ }
95
+ catch (error) {
96
+ return { content: formatErrorForMcp(error) };
97
+ }
98
+ });
99
+ // Unlink Task from Milestone
100
+ server.tool('unlink_task_from_milestone', 'Remove a task from a milestone.', {
101
+ project_id: z.string().uuid().describe('Project ID'),
102
+ milestone_id: z.string().uuid().describe('Milestone ID'),
103
+ task_id: z.string().uuid().describe('Task ID to unlink'),
104
+ }, async (input) => {
105
+ try {
106
+ await client.unlinkTaskFromMilestone(input.project_id, input.milestone_id, input.task_id);
107
+ return {
108
+ content: [{
109
+ type: 'text',
110
+ text: `Unlinked task ${input.task_id} from milestone ${input.milestone_id}`,
111
+ }],
112
+ };
113
+ }
114
+ catch (error) {
115
+ return { content: formatErrorForMcp(error) };
116
+ }
117
+ });
118
+ }
119
+ //# sourceMappingURL=milestones.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"milestones.js","sourceRoot":"","sources":["../../src/tools/milestones.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP tools for note management
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { JoanApiClient } from '../client/api-client.js';
6
+ export declare function registerNoteTools(server: McpServer, client: JoanApiClient): void;
7
+ //# sourceMappingURL=notes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notes.d.ts","sourceRoot":"","sources":["../../src/tools/notes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CA4FhF"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * MCP tools for note management
3
+ */
4
+ import { z } from 'zod';
5
+ import { formatErrorForMcp } from '../utils/errors.js';
6
+ export function registerNoteTools(server, client) {
7
+ // Create Note
8
+ server.tool('create_note', 'Create a new note in Joan.', {
9
+ title: z.string().min(1).describe('Note title'),
10
+ content: z.string().optional().describe('Note content (markdown supported)'),
11
+ folder_id: z.string().uuid().optional().describe('Folder ID to place note in'),
12
+ tags: z.array(z.string()).optional().describe('Note tags'),
13
+ is_pinned: z.boolean().optional().describe('Pin the note'),
14
+ }, async (input) => {
15
+ try {
16
+ const note = await client.createNote({
17
+ title: input.title,
18
+ content: input.content,
19
+ folder_id: input.folder_id,
20
+ tags: input.tags,
21
+ is_pinned: input.is_pinned,
22
+ });
23
+ return {
24
+ content: [{
25
+ type: 'text',
26
+ text: `Created note "${note.title}" (ID: ${note.id})`,
27
+ }],
28
+ };
29
+ }
30
+ catch (error) {
31
+ return { content: formatErrorForMcp(error) };
32
+ }
33
+ });
34
+ // Update Note
35
+ server.tool('update_note', 'Update an existing note in Joan.', {
36
+ note_id: z.string().uuid().describe('Note ID to update'),
37
+ title: z.string().min(1).optional().describe('New note title'),
38
+ content: z.string().optional().describe('New note content (markdown supported)'),
39
+ folder_id: z.string().uuid().optional().describe('Move to folder ID'),
40
+ tags: z.array(z.string()).optional().describe('New note tags'),
41
+ is_pinned: z.boolean().optional().describe('Pin/unpin the note'),
42
+ is_archived: z.boolean().optional().describe('Archive/unarchive the note'),
43
+ }, async (input) => {
44
+ try {
45
+ const note = await client.updateNote(input.note_id, {
46
+ title: input.title,
47
+ content: input.content,
48
+ folder_id: input.folder_id,
49
+ tags: input.tags,
50
+ is_pinned: input.is_pinned,
51
+ is_archived: input.is_archived,
52
+ });
53
+ return {
54
+ content: [{
55
+ type: 'text',
56
+ text: `Updated note "${note.title}" (ID: ${note.id})`,
57
+ }],
58
+ };
59
+ }
60
+ catch (error) {
61
+ return { content: formatErrorForMcp(error) };
62
+ }
63
+ });
64
+ // Delete Note
65
+ server.tool('delete_note', 'Delete a note from Joan.', {
66
+ note_id: z.string().uuid().describe('Note ID to delete'),
67
+ }, async (input) => {
68
+ try {
69
+ await client.deleteNote(input.note_id);
70
+ return {
71
+ content: [{
72
+ type: 'text',
73
+ text: `Note ${input.note_id} deleted`,
74
+ }],
75
+ };
76
+ }
77
+ catch (error) {
78
+ return { content: formatErrorForMcp(error) };
79
+ }
80
+ });
81
+ }
82
+ //# sourceMappingURL=notes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notes.js","sourceRoot":"","sources":["../../src/tools/notes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP tools for project management
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { JoanApiClient } from '../client/api-client.js';
6
+ export declare function registerProjectTools(server: McpServer, client: JoanApiClient): void;
7
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAmEnF"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * MCP tools for project management
3
+ */
4
+ import { z } from 'zod';
5
+ import { formatErrorForMcp } from '../utils/errors.js';
6
+ export function registerProjectTools(server, client) {
7
+ // Create Project
8
+ server.tool('create_project', 'Create a new project in Joan.', {
9
+ name: z.string().min(1).describe('Project name'),
10
+ description: z.string().optional().describe('Project description'),
11
+ status: z.enum(['planning', 'active', 'on_hold', 'completed', 'archived']).optional().describe('Project status'),
12
+ start_date: z.string().optional().describe('Start date (ISO 8601 format)'),
13
+ end_date: z.string().optional().describe('End date (ISO 8601 format)'),
14
+ }, async (input) => {
15
+ try {
16
+ const project = await client.createProject({
17
+ name: input.name,
18
+ description: input.description,
19
+ status: input.status,
20
+ start_date: input.start_date,
21
+ end_date: input.end_date,
22
+ });
23
+ return {
24
+ content: [{
25
+ type: 'text',
26
+ text: `Created project "${project.name}" (ID: ${project.id})`,
27
+ }],
28
+ };
29
+ }
30
+ catch (error) {
31
+ return { content: formatErrorForMcp(error) };
32
+ }
33
+ });
34
+ // Update Project
35
+ server.tool('update_project', 'Update an existing project in Joan.', {
36
+ project_id: z.string().uuid().describe('Project ID to update'),
37
+ name: z.string().min(1).optional().describe('New project name'),
38
+ description: z.string().optional().describe('New project description'),
39
+ status: z.enum(['planning', 'active', 'on_hold', 'completed', 'archived']).optional().describe('New project status'),
40
+ start_date: z.string().optional().describe('New start date (ISO 8601 format)'),
41
+ end_date: z.string().optional().describe('New end date (ISO 8601 format)'),
42
+ }, async (input) => {
43
+ try {
44
+ const project = await client.updateProject(input.project_id, {
45
+ name: input.name,
46
+ description: input.description,
47
+ status: input.status,
48
+ start_date: input.start_date,
49
+ end_date: input.end_date,
50
+ });
51
+ return {
52
+ content: [{
53
+ type: 'text',
54
+ text: `Updated project "${project.name}" (ID: ${project.id})`,
55
+ }],
56
+ };
57
+ }
58
+ catch (error) {
59
+ return { content: formatErrorForMcp(error) };
60
+ }
61
+ });
62
+ }
63
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP tools for task management
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { JoanApiClient } from '../client/api-client.js';
6
+ export declare function registerTaskTools(server: McpServer, client: JoanApiClient): void;
7
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAI7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAiJhF"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * MCP tools for task management
3
+ */
4
+ import { z } from 'zod';
5
+ import { formatErrorForMcp } from '../utils/errors.js';
6
+ import { formatTask, formatTaskInput } from '../utils/converters.js';
7
+ export function registerTaskTools(server, client) {
8
+ // Create Task
9
+ server.tool('create_task', 'Create a new task in Joan. Can be associated with a project or standalone.', {
10
+ title: z.string().min(1).describe('Task title'),
11
+ description: z.string().optional().describe('Task description'),
12
+ project_id: z.string().uuid().optional().describe('Project ID to create task in'),
13
+ column_id: z.string().uuid().optional().describe('Kanban column ID (for project tasks)'),
14
+ priority: z.enum(['none', 'low', 'medium', 'high']).optional().describe('Task priority'),
15
+ due_date: z.string().optional().describe('Due date (ISO 8601 format, e.g., 2025-12-31)'),
16
+ estimated_pomodoros: z.number().int().min(1).optional().describe('Estimated pomodoros (25 min each)'),
17
+ assignee_id: z.string().uuid().optional().describe('Assignee user ID'),
18
+ tags: z.array(z.string()).optional().describe('Task tags'),
19
+ }, async (input) => {
20
+ try {
21
+ const apiInput = formatTaskInput({
22
+ title: input.title,
23
+ description: input.description,
24
+ project_id: input.project_id,
25
+ column_id: input.column_id,
26
+ priority: input.priority,
27
+ due_date: input.due_date,
28
+ estimated_pomodoros: input.estimated_pomodoros,
29
+ tags: input.tags,
30
+ });
31
+ if (input.assignee_id) {
32
+ apiInput.assignee_id = input.assignee_id;
33
+ }
34
+ const task = await client.createTask(apiInput);
35
+ const formatted = formatTask(task);
36
+ return {
37
+ content: [{
38
+ type: 'text',
39
+ text: `Created task "${task.title}" (ID: ${task.id})${task.task_number ? ` #${task.task_number}` : ''}`,
40
+ }],
41
+ };
42
+ }
43
+ catch (error) {
44
+ return { content: formatErrorForMcp(error) };
45
+ }
46
+ });
47
+ // Update Task
48
+ server.tool('update_task', 'Update an existing task in Joan.', {
49
+ task_id: z.string().uuid().describe('Task ID to update'),
50
+ title: z.string().min(1).optional().describe('New task title'),
51
+ description: z.string().optional().describe('New task description'),
52
+ column_id: z.string().uuid().optional().describe('Move to column ID'),
53
+ status: z.enum(['todo', 'in_progress', 'done', 'cancelled']).optional().describe('New task status'),
54
+ priority: z.enum(['none', 'low', 'medium', 'high']).optional().describe('New priority'),
55
+ due_date: z.string().optional().describe('New due date (ISO 8601 format)'),
56
+ estimated_pomodoros: z.number().int().min(1).optional().describe('New estimated pomodoros'),
57
+ assignee_id: z.string().uuid().optional().describe('New assignee user ID'),
58
+ tags: z.array(z.string()).optional().describe('New task tags'),
59
+ }, async (input) => {
60
+ try {
61
+ const apiInput = formatTaskInput({
62
+ title: input.title || '',
63
+ description: input.description,
64
+ status: input.status,
65
+ priority: input.priority,
66
+ due_date: input.due_date,
67
+ estimated_pomodoros: input.estimated_pomodoros,
68
+ column_id: input.column_id,
69
+ tags: input.tags,
70
+ });
71
+ // Remove title if not provided
72
+ if (!input.title) {
73
+ delete apiInput.title;
74
+ }
75
+ if (input.assignee_id) {
76
+ apiInput.assignee_id = input.assignee_id;
77
+ }
78
+ const task = await client.updateTask(input.task_id, apiInput);
79
+ return {
80
+ content: [{
81
+ type: 'text',
82
+ text: `Updated task "${task.title}" (ID: ${task.id})`,
83
+ }],
84
+ };
85
+ }
86
+ catch (error) {
87
+ return { content: formatErrorForMcp(error) };
88
+ }
89
+ });
90
+ // Complete Task
91
+ server.tool('complete_task', 'Mark a task as completed.', {
92
+ task_id: z.string().uuid().describe('Task ID to complete'),
93
+ }, async (input) => {
94
+ try {
95
+ await client.completeTask(input.task_id);
96
+ return {
97
+ content: [{
98
+ type: 'text',
99
+ text: `Task ${input.task_id} marked as completed`,
100
+ }],
101
+ };
102
+ }
103
+ catch (error) {
104
+ return { content: formatErrorForMcp(error) };
105
+ }
106
+ });
107
+ // Delete Task
108
+ server.tool('delete_task', 'Delete a task.', {
109
+ task_id: z.string().uuid().describe('Task ID to delete'),
110
+ }, async (input) => {
111
+ try {
112
+ await client.deleteTask(input.task_id);
113
+ return {
114
+ content: [{
115
+ type: 'text',
116
+ text: `Task ${input.task_id} deleted`,
117
+ }],
118
+ };
119
+ }
120
+ catch (error) {
121
+ return { content: formatErrorForMcp(error) };
122
+ }
123
+ });
124
+ }
125
+ //# sourceMappingURL=tasks.js.map