Compare commits
3 Commits
fix/update
...
fix/mcp.is
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e5089c4cf | ||
|
|
f2d4f9668a | ||
|
|
4639eee097 |
5
.changeset/puny-friends-give.md
Normal file
5
.changeset/puny-friends-give.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"task-master-ai": patch
|
||||
---
|
||||
|
||||
Fix MCP server error when retrieving tools and resources
|
||||
@@ -32,10 +32,6 @@ class TaskMasterMCPServer {
|
||||
this.server = new FastMCP(this.options);
|
||||
this.initialized = false;
|
||||
|
||||
this.server.addResource({});
|
||||
|
||||
this.server.addResourceTemplate({});
|
||||
|
||||
// Bind methods
|
||||
this.init = this.init.bind(this);
|
||||
this.start = this.start.bind(this);
|
||||
|
||||
@@ -190,8 +190,45 @@ function parseUpdatedTaskFromText(text, expectedTaskId, logFn, isMCP) {
|
||||
throw new Error('Parsed AI response is not a valid JSON object.');
|
||||
}
|
||||
|
||||
// Preprocess the task to ensure subtasks have proper structure
|
||||
const preprocessedTask = {
|
||||
...parsedTask,
|
||||
status: parsedTask.status || 'pending',
|
||||
dependencies: Array.isArray(parsedTask.dependencies)
|
||||
? parsedTask.dependencies
|
||||
: [],
|
||||
details:
|
||||
typeof parsedTask.details === 'string'
|
||||
? parsedTask.details
|
||||
: String(parsedTask.details || ''),
|
||||
testStrategy:
|
||||
typeof parsedTask.testStrategy === 'string'
|
||||
? parsedTask.testStrategy
|
||||
: String(parsedTask.testStrategy || ''),
|
||||
// Ensure subtasks is an array and each subtask has required fields
|
||||
subtasks: Array.isArray(parsedTask.subtasks)
|
||||
? parsedTask.subtasks.map((subtask) => ({
|
||||
...subtask,
|
||||
title: subtask.title || '',
|
||||
description: subtask.description || '',
|
||||
status: subtask.status || 'pending',
|
||||
dependencies: Array.isArray(subtask.dependencies)
|
||||
? subtask.dependencies
|
||||
: [],
|
||||
details:
|
||||
typeof subtask.details === 'string'
|
||||
? subtask.details
|
||||
: String(subtask.details || ''),
|
||||
testStrategy:
|
||||
typeof subtask.testStrategy === 'string'
|
||||
? subtask.testStrategy
|
||||
: String(subtask.testStrategy || '')
|
||||
}))
|
||||
: []
|
||||
};
|
||||
|
||||
// Validate the parsed task object using Zod
|
||||
const validationResult = updatedTaskSchema.safeParse(parsedTask);
|
||||
const validationResult = updatedTaskSchema.safeParse(preprocessedTask);
|
||||
if (!validationResult.success) {
|
||||
report('error', 'Parsed task object failed Zod validation.');
|
||||
validationResult.error.errors.forEach((err) => {
|
||||
|
||||
@@ -196,7 +196,18 @@ function parseUpdatedTasksFromText(text, expectedCount, logFn, isMCP) {
|
||||
);
|
||||
}
|
||||
|
||||
const validationResult = updatedTaskArraySchema.safeParse(parsedTasks);
|
||||
// Preprocess tasks to ensure required fields have proper defaults
|
||||
const preprocessedTasks = parsedTasks.map((task) => ({
|
||||
...task,
|
||||
// Ensure subtasks is always an array (not null or undefined)
|
||||
subtasks: Array.isArray(task.subtasks) ? task.subtasks : [],
|
||||
// Ensure status has a default value if missing
|
||||
status: task.status || 'pending',
|
||||
// Ensure dependencies is always an array
|
||||
dependencies: Array.isArray(task.dependencies) ? task.dependencies : []
|
||||
}));
|
||||
|
||||
const validationResult = updatedTaskArraySchema.safeParse(preprocessedTasks);
|
||||
if (!validationResult.success) {
|
||||
report('error', 'Parsed task array failed Zod validation.');
|
||||
validationResult.error.errors.forEach((err) => {
|
||||
@@ -442,7 +453,17 @@ async function updateTasks(
|
||||
data.tasks.forEach((task, index) => {
|
||||
if (updatedTasksMap.has(task.id)) {
|
||||
// Only update if the task was part of the set sent to AI
|
||||
data.tasks[index] = updatedTasksMap.get(task.id);
|
||||
const updatedTask = updatedTasksMap.get(task.id);
|
||||
// Merge the updated task with the existing one to preserve fields like subtasks
|
||||
data.tasks[index] = {
|
||||
...task, // Keep all existing fields
|
||||
...updatedTask, // Override with updated fields
|
||||
// Ensure subtasks field is preserved if not provided by AI
|
||||
subtasks:
|
||||
updatedTask.subtasks !== undefined
|
||||
? updatedTask.subtasks
|
||||
: task.subtasks
|
||||
};
|
||||
actualUpdateCount++;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user