local-file-operation-mcp
Version:
本地文件操作 MCP 服务器:安全的读写、编辑、搜索、比较、哈希、权限、压缩、监控、命令与任务管理工具集。
266 lines (227 loc) • 7.43 kB
JavaScript
/**
* 任务管理工具模块
* 支持任务分解、排期、进度跟踪
* 数据存储在 ./temps/todo_<model_name>.json
*/
const fs = require('fs').promises;
const path = require('path');
class TaskManagerTool {
constructor(securityValidator) {
this.securityValidator = securityValidator;
this.tempsDir = path.join(__dirname, '..', 'temps');
}
async handle(args) {
const {
operation,
model_name = 'default',
task_id,
title,
description,
priority = 'medium',
due_date,
subtasks = [],
status = 'pending',
progress = 0
} = args;
try {
switch (operation) {
case 'create':
return await this.createTask(model_name, { title, description, priority, due_date, subtasks });
case 'update':
return await this.updateTask(model_name, task_id, { title, description, priority, due_date, subtasks, status, progress });
case 'delete':
return await this.deleteTask(model_name, task_id);
case 'list':
return await this.listTasks(model_name, status);
case 'complete':
return await this.completeTask(model_name, task_id);
case 'get':
return await this.getTask(model_name, task_id);
case 'clear':
return await this.clearAllTasks(model_name);
default:
throw new Error(`不支持的操作类型: ${operation}`);
}
} catch (error) {
throw new Error(`任务管理操作失败: ${error.message}`);
}
}
async createTask(modelName, taskData) {
const tasks = await this.loadTasks(modelName);
const taskId = this.generateTaskId();
const now = new Date().toISOString();
const newTask = {
id: taskId,
title: taskData.title,
description: taskData.description || '',
priority: taskData.priority,
due_date: taskData.due_date || null,
subtasks: taskData.subtasks || [],
status: 'pending',
progress: 0,
created_at: now,
updated_at: now
};
tasks.push(newTask);
await this.saveTasks(modelName, tasks);
return {
content: [
{
type: 'text',
text: `任务创建成功!\n任务ID: ${taskId}\n标题: ${newTask.title}\n优先级: ${newTask.priority}\n状态: ${newTask.status}`
}
]
};
}
async updateTask(modelName, taskId, updateData) {
const tasks = await this.loadTasks(modelName);
const taskIndex = tasks.findIndex(task => task.id === taskId);
if (taskIndex === -1) {
throw new Error(`任务不存在: ${taskId}`);
}
const task = tasks[taskIndex];
const now = new Date().toISOString();
// 更新任务数据
if (updateData.title !== undefined) task.title = updateData.title;
if (updateData.description !== undefined) task.description = updateData.description;
if (updateData.priority !== undefined) task.priority = updateData.priority;
if (updateData.due_date !== undefined) task.due_date = updateData.due_date;
if (updateData.subtasks !== undefined) task.subtasks = updateData.subtasks;
if (updateData.status !== undefined) task.status = updateData.status;
if (updateData.progress !== undefined) task.progress = updateData.progress;
task.updated_at = now;
await this.saveTasks(modelName, tasks);
return {
content: [
{
type: 'text',
text: `任务更新成功!\n任务ID: ${taskId}\n标题: ${task.title}\n状态: ${task.status}\n进度: ${task.progress}%`
}
]
};
}
async deleteTask(modelName, taskId) {
const tasks = await this.loadTasks(modelName);
const taskIndex = tasks.findIndex(task => task.id === taskId);
if (taskIndex === -1) {
throw new Error(`任务不存在: ${taskId}`);
}
const deletedTask = tasks.splice(taskIndex, 1)[0];
await this.saveTasks(modelName, tasks);
return {
content: [
{
type: 'text',
text: `任务删除成功!\n已删除任务: ${deletedTask.title} (ID: ${taskId})`
}
]
};
}
async listTasks(modelName, statusFilter = null) {
const tasks = await this.loadTasks(modelName);
let filteredTasks = tasks;
if (statusFilter) {
filteredTasks = tasks.filter(task => task.status === statusFilter);
}
if (filteredTasks.length === 0) {
return {
content: [
{
type: 'text',
text: `没有找到任务${statusFilter ? ` (状态: ${statusFilter})` : ''}`
}
]
};
}
const taskList = filteredTasks.map(task => {
const dueDate = task.due_date ? `截止: ${task.due_date}` : '无截止日期';
const subtasksInfo = task.subtasks.length > 0 ? `子任务: ${task.subtasks.length}个` : '无子任务';
return `[${task.id}] ${task.title}
状态: ${task.status} | 优先级: ${task.priority} | 进度: ${task.progress}%
${dueDate} | ${subtasksInfo}
描述: ${task.description}
创建时间: ${task.created_at}
${'='.repeat(50)}`;
}).join('\n');
return {
content: [
{
type: 'text',
text: `任务列表 (${filteredTasks.length}个任务):\n\n${taskList}`
}
]
};
}
async completeTask(modelName, taskId) {
return await this.updateTask(modelName, taskId, {
status: 'completed',
progress: 100
});
}
async getTask(modelName, taskId) {
const tasks = await this.loadTasks(modelName);
const task = tasks.find(task => task.id === taskId);
if (!task) {
throw new Error(`任务不存在: ${taskId}`);
}
const subtasksList = task.subtasks.length > 0
? task.subtasks.map((subtask, index) => `${index + 1}. ${subtask}`).join('\n')
: '无子任务';
return {
content: [
{
type: 'text',
text: `任务详情:
ID: ${task.id}
标题: ${task.title}
描述: ${task.description}
状态: ${task.status}
优先级: ${task.priority}
进度: ${task.progress}%
截止日期: ${task.due_date || '无'}
创建时间: ${task.created_at}
更新时间: ${task.updated_at}
子任务:
${subtasksList}`
}
]
};
}
async clearAllTasks(modelName) {
await this.saveTasks(modelName, []);
return {
content: [
{
type: 'text',
text: `已清空所有任务 (模型: ${modelName})`
}
]
};
}
async loadTasks(modelName) {
try {
const filePath = this.getTaskFilePath(modelName);
const data = await fs.readFile(filePath, 'utf8');
return JSON.parse(data);
} catch (error) {
if (error.code === 'ENOENT') {
return []; // 文件不存在,返回空数组
}
throw error;
}
}
async saveTasks(modelName, tasks) {
const filePath = this.getTaskFilePath(modelName);
await fs.mkdir(path.dirname(filePath), { recursive: true });
await fs.writeFile(filePath, JSON.stringify(tasks, null, 2), 'utf8');
}
getTaskFilePath(modelName) {
// 清理模型名称,移除特殊字符
const cleanModelName = modelName.replace(/[^a-zA-Z0-9_-]/g, '_');
return path.join(this.tempsDir, `todo_${cleanModelName}.json`);
}
generateTaskId() {
return 'task_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
}
}
module.exports = TaskManagerTool;