@doist/todoist-ai 2.0.0 → 2.0.1
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 +7 -0
- package/dist/index.d.ts +18 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -48
- package/dist/main.js +6 -11
- package/dist/mcp-helpers.d.ts +2 -2
- package/dist/mcp-helpers.d.ts.map +1 -1
- package/dist/mcp-helpers.js +1 -4
- package/dist/mcp-server.d.ts +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +34 -36
- package/dist/todoist-tool.js +1 -2
- package/dist/tool-helpers.d.ts +11 -1
- package/dist/tool-helpers.d.ts.map +1 -1
- package/dist/tool-helpers.js +41 -22
- package/dist/tool-helpers.test.js +35 -14
- package/dist/tools/__tests__/delete-one.test.d.ts +2 -0
- package/dist/tools/__tests__/delete-one.test.d.ts.map +1 -0
- package/dist/tools/__tests__/delete-one.test.js +90 -0
- package/dist/tools/__tests__/overview.test.d.ts +2 -0
- package/dist/tools/__tests__/overview.test.d.ts.map +1 -0
- package/dist/tools/__tests__/overview.test.js +163 -0
- package/dist/tools/__tests__/projects-list.test.d.ts +2 -0
- package/dist/tools/__tests__/projects-list.test.d.ts.map +1 -0
- package/dist/tools/__tests__/projects-list.test.js +140 -0
- package/dist/tools/__tests__/projects-manage.test.d.ts +2 -0
- package/dist/tools/__tests__/projects-manage.test.d.ts.map +1 -0
- package/dist/tools/__tests__/projects-manage.test.js +106 -0
- package/dist/tools/__tests__/sections-manage.test.d.ts +2 -0
- package/dist/tools/__tests__/sections-manage.test.d.ts.map +1 -0
- package/dist/tools/__tests__/sections-manage.test.js +138 -0
- package/dist/tools/__tests__/sections-search.test.d.ts +2 -0
- package/dist/tools/__tests__/sections-search.test.d.ts.map +1 -0
- package/dist/tools/__tests__/sections-search.test.js +235 -0
- package/dist/tools/__tests__/tasks-add-multiple.test.d.ts +2 -0
- package/dist/tools/__tests__/tasks-add-multiple.test.d.ts.map +1 -0
- package/dist/tools/__tests__/tasks-add-multiple.test.js +160 -0
- package/dist/tools/__tests__/tasks-complete-multiple.test.d.ts +2 -0
- package/dist/tools/__tests__/tasks-complete-multiple.test.d.ts.map +1 -0
- package/dist/tools/__tests__/tasks-complete-multiple.test.js +146 -0
- package/dist/tools/__tests__/tasks-list-by-date.test.d.ts +2 -0
- package/dist/tools/__tests__/tasks-list-by-date.test.d.ts.map +1 -0
- package/dist/tools/__tests__/tasks-list-by-date.test.js +192 -0
- package/dist/tools/__tests__/tasks-list-completed.test.d.ts +2 -0
- package/dist/tools/__tests__/tasks-list-completed.test.d.ts.map +1 -0
- package/dist/tools/__tests__/tasks-list-completed.test.js +154 -0
- package/dist/tools/__tests__/tasks-list-for-container.test.d.ts +2 -0
- package/dist/tools/__tests__/tasks-list-for-container.test.d.ts.map +1 -0
- package/dist/tools/__tests__/tasks-list-for-container.test.js +232 -0
- package/dist/tools/__tests__/tasks-organize-multiple.test.d.ts +2 -0
- package/dist/tools/__tests__/tasks-organize-multiple.test.d.ts.map +1 -0
- package/dist/tools/__tests__/tasks-organize-multiple.test.js +245 -0
- package/dist/tools/__tests__/tasks-search.test.d.ts +2 -0
- package/dist/tools/__tests__/tasks-search.test.d.ts.map +1 -0
- package/dist/tools/__tests__/tasks-search.test.js +106 -0
- package/dist/tools/__tests__/tasks-update-one.test.d.ts +2 -0
- package/dist/tools/__tests__/tasks-update-one.test.d.ts.map +1 -0
- package/dist/tools/__tests__/tasks-update-one.test.js +161 -0
- package/dist/tools/delete-one.js +4 -7
- package/dist/tools/overview.js +8 -11
- package/dist/tools/projects-list.js +7 -10
- package/dist/tools/projects-manage.js +6 -9
- package/dist/tools/sections-manage.js +7 -10
- package/dist/tools/sections-search.js +4 -7
- package/dist/tools/tasks-add-multiple.js +13 -16
- package/dist/tools/tasks-complete-multiple.js +3 -6
- package/dist/tools/tasks-list-by-date.js +12 -15
- package/dist/tools/tasks-list-completed.d.ts +1 -1
- package/dist/tools/tasks-list-completed.js +13 -16
- package/dist/tools/tasks-list-for-container.js +8 -11
- package/dist/tools/tasks-organize-multiple.d.ts.map +1 -1
- package/dist/tools/tasks-organize-multiple.js +20 -14
- package/dist/tools/tasks-search.js +7 -10
- package/dist/tools/tasks-update-one.d.ts +2 -2
- package/dist/tools/tasks-update-one.d.ts.map +1 -1
- package/dist/tools/tasks-update-one.js +22 -15
- package/dist/tools/test-helpers.d.ts +79 -0
- package/dist/tools/test-helpers.d.ts.map +1 -0
- package/dist/tools/test-helpers.js +139 -0
- package/package.json +6 -2
- package/scripts/test-executable.cjs +69 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a mock Task with all required properties and sensible defaults.
|
|
3
|
+
* Pass only the properties you want to override for your specific test.
|
|
4
|
+
*/
|
|
5
|
+
export function createMockTask(overrides = {}) {
|
|
6
|
+
return {
|
|
7
|
+
id: '8485093748',
|
|
8
|
+
content: 'Test task content',
|
|
9
|
+
description: '',
|
|
10
|
+
completedAt: null,
|
|
11
|
+
labels: [],
|
|
12
|
+
childOrder: 1,
|
|
13
|
+
priority: 1,
|
|
14
|
+
projectId: '6cfCcrrCFg2xP94Q',
|
|
15
|
+
sectionId: null,
|
|
16
|
+
parentId: null,
|
|
17
|
+
url: 'https://todoist.com/showTask?id=8485093748',
|
|
18
|
+
// Use correct property names from Task schema
|
|
19
|
+
noteCount: 0,
|
|
20
|
+
addedByUid: '713437',
|
|
21
|
+
addedAt: '2025-08-13T22:09:56.123456Z',
|
|
22
|
+
deadline: null,
|
|
23
|
+
responsibleUid: null,
|
|
24
|
+
assignedByUid: null,
|
|
25
|
+
isCollapsed: false,
|
|
26
|
+
isDeleted: false,
|
|
27
|
+
duration: null,
|
|
28
|
+
checked: false,
|
|
29
|
+
updatedAt: '2025-08-13T22:09:56.123456Z',
|
|
30
|
+
due: null,
|
|
31
|
+
dayOrder: 0,
|
|
32
|
+
userId: '713437',
|
|
33
|
+
...overrides,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Creates a mock Section with all required properties and sensible defaults.
|
|
38
|
+
* Pass only the properties you want to override for your specific test.
|
|
39
|
+
*/
|
|
40
|
+
export function createMockSection(overrides = {}) {
|
|
41
|
+
return {
|
|
42
|
+
id: 'section-123',
|
|
43
|
+
projectId: '6cfCcrrCFg2xP94Q',
|
|
44
|
+
sectionOrder: 1,
|
|
45
|
+
userId: 'test-user',
|
|
46
|
+
addedAt: '2024-01-01T00:00:00Z',
|
|
47
|
+
updatedAt: '2024-01-01T00:00:00Z',
|
|
48
|
+
archivedAt: null,
|
|
49
|
+
isArchived: false,
|
|
50
|
+
isDeleted: false,
|
|
51
|
+
isCollapsed: false,
|
|
52
|
+
name: 'Test Section',
|
|
53
|
+
...overrides,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Creates a mock PersonalProject with all required properties and sensible defaults.
|
|
58
|
+
* Pass only the properties you want to override for your specific test.
|
|
59
|
+
*/
|
|
60
|
+
export function createMockProject(overrides = {}) {
|
|
61
|
+
return {
|
|
62
|
+
id: '6cfCcrrCFg2xP94Q',
|
|
63
|
+
name: 'Test Project',
|
|
64
|
+
color: 'charcoal',
|
|
65
|
+
isFavorite: false,
|
|
66
|
+
isShared: false,
|
|
67
|
+
parentId: null,
|
|
68
|
+
inboxProject: false,
|
|
69
|
+
viewStyle: 'list',
|
|
70
|
+
url: 'https://todoist.com/projects/6cfCcrrCFg2xP94Q',
|
|
71
|
+
isDeleted: false,
|
|
72
|
+
updatedAt: '2025-08-13T22:09:55.841800Z',
|
|
73
|
+
createdAt: '2025-08-13T22:09:55.841785Z',
|
|
74
|
+
childOrder: 1,
|
|
75
|
+
defaultOrder: 0,
|
|
76
|
+
description: '',
|
|
77
|
+
isCollapsed: false,
|
|
78
|
+
canAssignTasks: false,
|
|
79
|
+
isFrozen: false,
|
|
80
|
+
isArchived: false,
|
|
81
|
+
...overrides,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Creates a mock API response object with results and nextCursor.
|
|
86
|
+
*/
|
|
87
|
+
export function createMockApiResponse(results, nextCursor = null) {
|
|
88
|
+
return {
|
|
89
|
+
results,
|
|
90
|
+
nextCursor,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Creates a simplified mapped task (matches mapTask output) for filter-based query tests.
|
|
95
|
+
*/
|
|
96
|
+
export function createMappedTask(overrides = {}) {
|
|
97
|
+
return {
|
|
98
|
+
id: TEST_IDS.TASK_1,
|
|
99
|
+
content: 'Test task content',
|
|
100
|
+
description: '',
|
|
101
|
+
dueDate: undefined,
|
|
102
|
+
recurring: false,
|
|
103
|
+
priority: 1,
|
|
104
|
+
projectId: TEST_IDS.PROJECT_TEST,
|
|
105
|
+
sectionId: null,
|
|
106
|
+
parentId: null,
|
|
107
|
+
labels: [],
|
|
108
|
+
...overrides,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Common error messages used across tests.
|
|
113
|
+
*/
|
|
114
|
+
export const TEST_ERRORS = {
|
|
115
|
+
API_RATE_LIMIT: 'API Error: Rate limit exceeded',
|
|
116
|
+
API_UNAUTHORIZED: 'API Error: Unauthorized',
|
|
117
|
+
INVALID_CURSOR: 'Invalid cursor format',
|
|
118
|
+
INVALID_FILTER: 'Invalid filter query',
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Creates multiple test cases for parameterized testing.
|
|
122
|
+
*/
|
|
123
|
+
export function createTestCases(cases) {
|
|
124
|
+
return cases;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Common mock IDs used across tests for consistency.
|
|
128
|
+
*/
|
|
129
|
+
export const TEST_IDS = {
|
|
130
|
+
TASK_1: '8485093748',
|
|
131
|
+
TASK_2: '8485093749',
|
|
132
|
+
TASK_3: '8485093750',
|
|
133
|
+
PROJECT_INBOX: 'inbox-project-id',
|
|
134
|
+
PROJECT_WORK: 'work-project-id',
|
|
135
|
+
PROJECT_TEST: '6cfCcrrCFg2xP94Q',
|
|
136
|
+
SECTION_1: 'section-123',
|
|
137
|
+
SECTION_2: 'section-456',
|
|
138
|
+
USER_ID: '713437',
|
|
139
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doist/todoist-ai",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"main": "./dist/index.js",
|
|
5
6
|
"types": "./dist/index.d.ts",
|
|
6
7
|
"files": [
|
|
7
8
|
"dist",
|
|
9
|
+
"scripts",
|
|
8
10
|
"package.json",
|
|
9
11
|
"LICENSE.txt",
|
|
10
12
|
"README.md"
|
|
@@ -23,8 +25,10 @@
|
|
|
23
25
|
"scripts": {
|
|
24
26
|
"test": "jest",
|
|
25
27
|
"build": "rimraf dist && npx tsc --project tsconfig.json",
|
|
26
|
-
"
|
|
28
|
+
"start": "npm run build && npx @modelcontextprotocol/inspector node dist/main.js",
|
|
29
|
+
"dev": "concurrently \"npx tsc --watch\" \"nodemon --watch dist --ext js --exec 'npx @modelcontextprotocol/inspector node dist/main.js'\"",
|
|
27
30
|
"setup": "cp .env.example .env && npm install && npm run build",
|
|
31
|
+
"test:executable": "npm run build && node scripts/test-executable.cjs",
|
|
28
32
|
"type-check": "npx tsc --noEmit",
|
|
29
33
|
"biome:sort-imports": "biome check --formatter-enabled=false --linter-enabled=false --organize-imports-enabled=true --write .",
|
|
30
34
|
"lint:check": "biome lint",
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('node:child_process')
|
|
4
|
+
const path = require('node:path')
|
|
5
|
+
|
|
6
|
+
console.log('Testing MCP server executable...')
|
|
7
|
+
|
|
8
|
+
const mainJs = path.join(__dirname, '..', 'dist', 'main.js')
|
|
9
|
+
const child = spawn('node', [mainJs], {
|
|
10
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
let _stdoutOutput = ''
|
|
14
|
+
let stderrOutput = ''
|
|
15
|
+
let hasError = false
|
|
16
|
+
|
|
17
|
+
child.stdout.on('data', (data) => {
|
|
18
|
+
_stdoutOutput += data.toString()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
child.stderr.on('data', (data) => {
|
|
22
|
+
const output = data.toString()
|
|
23
|
+
stderrOutput += output
|
|
24
|
+
|
|
25
|
+
// Only consider it an error if it's not related to graceful shutdown
|
|
26
|
+
if (output.includes('Error:') && !output.includes('SIGTERM') && !output.includes('SIGKILL')) {
|
|
27
|
+
console.error('Server startup error detected:', output)
|
|
28
|
+
hasError = true
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
child.on('error', (error) => {
|
|
33
|
+
console.error('Failed to start MCP server:', error.message)
|
|
34
|
+
hasError = true
|
|
35
|
+
process.exit(1)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
child.on('exit', (code, signal) => {
|
|
39
|
+
// Expected signals when we kill the process
|
|
40
|
+
if (signal === 'SIGTERM' || signal === 'SIGKILL') {
|
|
41
|
+
return // This is expected
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Unexpected exit codes during startup
|
|
45
|
+
if (code !== null && code !== 0) {
|
|
46
|
+
console.error(`Server exited unexpectedly with code ${code}`)
|
|
47
|
+
hasError = true
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// Kill the process after 2 seconds (MCP server should start successfully)
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
if (hasError) {
|
|
54
|
+
console.error('❌ MCP server failed to start properly')
|
|
55
|
+
if (stderrOutput.trim()) {
|
|
56
|
+
console.error('Error output:', stderrOutput.trim())
|
|
57
|
+
}
|
|
58
|
+
process.exit(1)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Gracefully terminate
|
|
62
|
+
child.kill('SIGTERM')
|
|
63
|
+
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
console.log('✅ MCP server executable test passed')
|
|
66
|
+
console.log('Server started successfully and is ready to accept connections')
|
|
67
|
+
process.exit(0)
|
|
68
|
+
}, 200) // Give it a moment to clean up
|
|
69
|
+
}, 2000)
|