todoist-mcp 1.3.3 → 1.3.4
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 +3 -1
- package/dist/index.js +3 -0
- package/dist/tools/sync.d.ts +1 -0
- package/dist/tools/sync.js +36 -0
- package/dist/tools/tasks.js +7 -1
- package/dist/utils/instructions.d.ts +4 -0
- package/dist/utils/instructions.js +49 -0
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
- **Projects**: Create and manage projects and sections
|
|
21
21
|
- **Comments**: Add and manage comments on tasks and projects
|
|
22
22
|
- **Labels**: Create and manage personal and shared labels
|
|
23
|
+
- **Smart Context**: On startup, automatically provides your projects and labels to the AI via server instructions — no extra tool calls needed
|
|
23
24
|
- **Prompt Support**: You can easily provide information about your projects to client
|
|
24
25
|
|
|
25
26
|
## Configuration
|
|
@@ -73,7 +74,8 @@ API_KEY = "your_todoist_api_token"
|
|
|
73
74
|
|
|
74
75
|
### Tasks
|
|
75
76
|
|
|
76
|
-
- `get_tasks_list`: Get tasks with optional filtering by project, section, label,
|
|
77
|
+
- `get_tasks_list`: Get tasks with optional filtering by project, section, label, or IDs
|
|
78
|
+
- `get_tasks_by_filter`: Get tasks using Todoist filter language (e.g. `"today"`, `"overdue"`, `"P1 | P2"`, `"#Work & @urgent"`)
|
|
77
79
|
- `create_tasks`: Create new tasks with various attributes
|
|
78
80
|
- `get_tasks`: Get specific tasks by ID or name
|
|
79
81
|
- `update_tasks`: Update existing tasks
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { server } from './clients.js';
|
|
4
4
|
import { config, log } from './utils/helpers.js';
|
|
5
|
+
import { buildInstructions } from './utils/instructions.js';
|
|
5
6
|
import './prompts.js';
|
|
6
7
|
import './tools.js';
|
|
7
8
|
export async function main() {
|
|
@@ -10,6 +11,8 @@ export async function main() {
|
|
|
10
11
|
process.exit(1);
|
|
11
12
|
}
|
|
12
13
|
try {
|
|
14
|
+
server.server._instructions =
|
|
15
|
+
await buildInstructions();
|
|
13
16
|
const transport = new StdioServerTransport();
|
|
14
17
|
await server.connect(transport);
|
|
15
18
|
process.stdin.resume();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { todoistApi } from '../clients.js';
|
|
3
|
+
import { createHandler } from '../utils/handlers.js';
|
|
4
|
+
const VALID_RESOURCE_TYPES = [
|
|
5
|
+
'labels',
|
|
6
|
+
'projects',
|
|
7
|
+
'items',
|
|
8
|
+
'notes',
|
|
9
|
+
'sections',
|
|
10
|
+
'filters',
|
|
11
|
+
'reminders',
|
|
12
|
+
'locations',
|
|
13
|
+
'user',
|
|
14
|
+
'live_notifications',
|
|
15
|
+
'collaborators',
|
|
16
|
+
'user_settings',
|
|
17
|
+
'notification_settings',
|
|
18
|
+
'user_plan_limits',
|
|
19
|
+
'completed_info',
|
|
20
|
+
'stats',
|
|
21
|
+
'workspaces',
|
|
22
|
+
'workspace_users',
|
|
23
|
+
];
|
|
24
|
+
createHandler('read_resources', `Read resources from the Todoist Sync API. Fetches one or more resource types in a single request. Available resource types: ${VALID_RESOURCE_TYPES.join(', ')}. Use sync_token '*' for a full sync, or pass a previously returned sync_token for incremental updates.`, {
|
|
25
|
+
resource_types: z
|
|
26
|
+
.array(z.string())
|
|
27
|
+
.min(1)
|
|
28
|
+
.describe(`Array of resource types to fetch. Valid types: ${VALID_RESOURCE_TYPES.join(', ')}`),
|
|
29
|
+
sync_token: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.default('*')
|
|
33
|
+
.describe('Sync token for incremental sync. Use "*" for full sync (default)'),
|
|
34
|
+
}, async (args) => {
|
|
35
|
+
return todoistApi.readResources(args.resource_types, args.sync_token);
|
|
36
|
+
});
|
package/dist/tools/tasks.js
CHANGED
|
@@ -12,7 +12,13 @@ const create_fields = {
|
|
|
12
12
|
.optional()
|
|
13
13
|
.describe('Description (detailed). May contain markdown-formatted text and hyperlinks'),
|
|
14
14
|
labels: z.array(z.string()).optional(),
|
|
15
|
-
priority: z
|
|
15
|
+
priority: z
|
|
16
|
+
.number()
|
|
17
|
+
.int()
|
|
18
|
+
.min(1)
|
|
19
|
+
.max(4)
|
|
20
|
+
.optional()
|
|
21
|
+
.describe('Todoist API priority (1-4): pass 4 when the user says "P1" or "highest priority", and pass 1 for "P4" or lowest priority'),
|
|
16
22
|
due_string: z
|
|
17
23
|
.string()
|
|
18
24
|
.optional()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { todoistApi } from '../clients.js';
|
|
2
|
+
import { log } from './helpers.js';
|
|
3
|
+
const HEADER = 'Use this server to interact with Todoist API.';
|
|
4
|
+
const PREVIEW_LIMIT = 20;
|
|
5
|
+
const NOTES = [
|
|
6
|
+
'Notes:',
|
|
7
|
+
'- Todoist API priority is inverted: P1 (urgent) = 4, P2 = 3, P3 = 2, P4 (normal) = 1',
|
|
8
|
+
].join('\n');
|
|
9
|
+
/**
|
|
10
|
+
* Truncates a list and appends "(+N more)" if it exceeds the limit
|
|
11
|
+
*/
|
|
12
|
+
function truncateList(items) {
|
|
13
|
+
const visible = items.slice(0, PREVIEW_LIMIT);
|
|
14
|
+
const remaining = items.length - visible.length;
|
|
15
|
+
const result = visible.join(', ');
|
|
16
|
+
return remaining > 0 ? `${result} (+${remaining} more)` : result;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fetches user context (projects, labels) and builds dynamic server instructions
|
|
20
|
+
*/
|
|
21
|
+
export async function buildInstructions() {
|
|
22
|
+
try {
|
|
23
|
+
const [projects, personalLabels, sharedLabels] = await Promise.all([
|
|
24
|
+
todoistApi.get('/projects', {}),
|
|
25
|
+
todoistApi.get('/labels', {}),
|
|
26
|
+
todoistApi.get('/labels/shared', {}),
|
|
27
|
+
]);
|
|
28
|
+
const parts = [HEADER];
|
|
29
|
+
if (Array.isArray(projects) && projects.length > 0) {
|
|
30
|
+
const projectList = projects
|
|
31
|
+
.map((p) => `- ${p.name} (id: ${p.id})`)
|
|
32
|
+
.join('\n');
|
|
33
|
+
parts.push(`\nUser projects:\n${projectList}`);
|
|
34
|
+
}
|
|
35
|
+
if (Array.isArray(personalLabels) && personalLabels.length > 0) {
|
|
36
|
+
const names = personalLabels.map((l) => l.name);
|
|
37
|
+
parts.push(`\nPersonal labels: ${truncateList(names)}`);
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(sharedLabels) && sharedLabels.length > 0) {
|
|
40
|
+
parts.push(`\nShared labels: ${truncateList(sharedLabels)}`);
|
|
41
|
+
}
|
|
42
|
+
parts.push(`\n${NOTES}`);
|
|
43
|
+
return parts.join('');
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
log('Failed to fetch user context for instructions:', error);
|
|
47
|
+
return `${HEADER}\n\n${NOTES}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
package/dist/utils/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.3.
|
|
1
|
+
export declare const version = "1.3.4";
|
package/dist/utils/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated file, do not edit
|
|
2
|
-
export const version = '1.3.
|
|
2
|
+
export const version = '1.3.4';
|