任务MCP服务器
一个轻量级的模型上下文协议(MCP)服务器,用于在代理AI开发过程中跟踪任务和子任务。为Claude Code和Claude Desktop集成提供每个项目工作区的独立SQLite数据库。
v0.4.0的新增功能🎉
发布: 2025-11-02
- 🛡️ 工作区元数据跟踪:任务创建时自动捕获工作空间上下文
- 🔍 工作区验证:
validate_task_workspace检测跨项目污染的工具 - 📋 全面审计:
audit_workspace_integrity全工作区健康检查工具 - 📖 审计指南:完整的文档 工作空间-审计指南.md
- 🔐 污染预防:及早发现和清理错位的任务
所有更改都与v0.3.0向后兼容。看 更改日志.md 了解全部细节。
以往版本
v0.3.0 (2025-10-29)
- 🏢 实体系统:跟踪具有多对多任务关系的文件、供应商和其他实体
- 🔗 实体链接:7个新的MCP工具,用于实体CRUD和链接到任务
- 📊 通用元数据:用于实体特定数据的灵活JSON存储
- 🗂️ 基于标签的发现:按类型和标签筛选实体,以便快速发现
v0.2.0版本 (2025-10-27)
- ✨ 在中自动捕获对话ID
created_by领域 - 🕐 ISO 8601时间戳格式
- 🔧 任务的真正部分更新
特性
🎯 核心能力
- 项目隔离:每个工作区单独的SQLite数据库(自动检测)
- 任务层次结构:具有无限嵌套的父/子任务关系
- 依赖项:带有验证的显式任务依赖关系
- 状态跟踪:状态机工作流(todo→ 正在进行中→ 阻塞→ done → 取消)
- 软删除:永久删除前保留30天
- 全文检索:按标题和描述搜索任务
- 标签组织:用空格分隔标签并进行规范化
- 并发访问:SQLite WAL模式,用于同时读取Claude代码和桌面
- 实体跟踪:跟踪具有多对多任务关系的文件、供应商和其他实体
- 通用元数据:用于实体特定数据的灵活JSON存储
- 实体链接:任务和实体之间的多对多关系具有软删除级联
- 工作区验证:自动元数据捕获和跨项目污染检测
- 诚信审计:全面的工作空间健康检查,并提供可操作的建议
🔒 数据验证
- 描述长度限制(10000个字符)
- 状态/优先级枚举验证
- 状态=“阻塞”时的阻塞原因要求
- 任务完成前的依赖关系解决
- 标签规范化(小写,单空格)
📊 数据库架构
- 每个项目数据库:
~/.task-mcp/databases/project_{hash}.db - 主注册表:
~/.task-mcp/master.db(跨客户端发现) - 工作空间检测:显式参数→ TASK_MCP_WORKSPACE环境→ 当前目录
- 路径哈希:SHA256截断为8个字符以确保文件名安全
安装
先决条件
- Python 3.9或更高版本
- 紫外线 包管理器(推荐)
从源代码安装
# Clone repository
git clone https://github.com/Ravenight13/simple-task-tracker-mcp.git
cd simple-task-tracker-mcp
# Install dependencies
uv sync --dev
# Verify installation
uv run task-mcp --help作为软件包安装
# Install with uv
uv pip install git+https://github.com/Ravenight13/simple-task-tracker-mcp.git
# Or with pip
pip install git+https://github.com/Ravenight13/simple-task-tracker-mcp.git配置
克劳德桌面
添加到 claude_desktop_config.json:
{
"mcpServers": {
"task-mcp": {
"command": "uv",
"args": ["run", "task-mcp"],
"env": {
"TASK_MCP_WORKSPACE": "/path/to/your/project"
}
}
}
}地点:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - 窗户:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
克劳德代码
对于Claude Code,服务器会自动从当前工作目录中检测工作区。添加到 .claude/config.json:
{
"mcpServers": {
"task-mcp": {
"command": "uv",
"args": ["run", "task-mcp"]
}
}
}这 TASK_MCP_WORKSPACE 环境变量由Claude Code根据活动项目自动设置。
快速开始
任务
# Via MCP tool
create_task(
title="Implement authentication API",
description="Add JWT-based authentication to the REST API",
status="todo",
priority="high",
tags="backend api authentication"
)列出任务
# Get all tasks
list_tasks()
# Filter by status
list_tasks(status="in_progress")
# Filter by priority and tags
list_tasks(priority="high", tags="backend")搜索任务
# Full-text search
search_tasks("authentication")更新任务状态
update_task(
task_id=1,
status="in_progress"
)创建子任务
# Create parent task
parent = create_task(title="Build Authentication System")
# Create subtasks
create_task(
title="Design database schema",
parent_task_id=parent['id']
)
create_task(
title="Implement JWT generation",
parent_task_id=parent['id']
)
# Get full task tree
get_task_tree(parent['id'])任务相关性
# Create tasks with dependencies
task1 = create_task(title="Set up database")
task2 = create_task(title="Create API endpoints", depends_on=[task1['id']])
# Get next actionable tasks (no unresolved dependencies)
get_next_tasks()MCP工具参考
核心CRUD操作
创建任务
创建具有验证功能的新任务。
参数:
title(str,必填):任务标题workspace_path(str|None):可选工作区路径(自动检测)description(str |无):任务描述(最多10k个字符)status(str):任务状态(默认:“todo”)priority(str):优先级(默认值:“中等”)parent_task_id(int|None):子任务的父任务IDdepends_on(list\[int\]|None):这取决于任务ID的列表tags(str|None):空格分隔的标签file_references(list\[str\]|无):文件路径列表created_by(str |无):对话ID
退货: 包含所有字段的任务对象
例子:
task = create_task(
title="Implement user registration",
description="Create registration endpoint with email validation",
priority="high",
tags="backend api user-management",
file_references=["src/api/auth.py", "tests/test_auth.py"]
)获取任务
按ID获取单个任务。
参数:
task_id(int,必填):任务IDworkspace_path(str|None):可选工作区路径
退货: 任务对象
例子:
task = get_task(task_id=1)
print(task['title'], task['status'])update_task
使用验证更新现有任务。
参数:
task_id(int,必填):任务IDworkspace_path(str|None):可选工作区路径title(str |无):更新标题description(str |无):更新描述status(str |无):更新状态priority(str |无):已更新优先级blocker_reason(str|None):当状态=“锁定”时为必填项- 其他需要的字段
退货: 已更新任务对象
例子:
# Mark task as blocked
update_task(
task_id=1,
status="blocked",
blocker_reason="Waiting for API key from infrastructure team"
)
# Complete task
update_task(task_id=1, status="done")list_tasks
列出带有可选筛选器的任务。
参数:
workspace_path(str|None):可选工作区路径status(str|None):按状态筛选priority(str|None):按优先级筛选parent_task_id(int|None):按父任务筛选tags(str|None):按标签筛选(部分匹配)
退货: 任务对象列表
例子:
# Get all high-priority in-progress tasks
tasks = list_tasks(status="in_progress", priority="high")
# Get all subtasks of a parent
subtasks = list_tasks(parent_task_id=5)
# Get tasks by tag
backend_tasks = list_tasks(tags="backend")搜索任务
任务标题和描述的全文搜索。
参数:
search_term(str,必填):搜索词workspace_path(str|None):可选工作区路径
退货: 匹配任务列表
例子:
results = search_tasks("authentication")删除任务
软删除任务(设置deleted_at时间戳)。
参数:
task_id(int,必填):任务IDworkspace_path(str|None):可选工作区路径cascade(bool):如果为True,也删除所有子任务(默认值:False)
退货: 已删除计数的成功确认
例子:
# Delete single task
delete_task(task_id=1)
# Delete task and all subtasks
delete_task(task_id=1, cascade=True)高级查询工具
get_task_tree
获取包含所有子代子任务的任务(递归)。
参数:
task_id(int,必填):根任务IDworkspace_path(str|None):可选工作区路径
退货: 带有嵌套“子任务”字段的任务对象
例子:
tree = get_task_tree(task_id=1)
print(tree['title'])
for subtask in tree['subtasks']:
print(f" - {subtask['title']}")get_blocked_tasks
获取状态为“已锁定”的所有任务。
参数:
workspace_path(str|None):可选工作区路径
退货: 带有blocker_reason的已阻止任务列表
例子:
blocked = get_blocked_tasks()
for task in blocked:
print(f"{task['title']}: {task['blocker_reason']}")get_ext_tasks
获取可操作的任务(状态=“todo”,没有未解决的依赖关系)。
参数:
workspace_path(str|None):可选工作区路径
退货: 按优先级DESC排序的可操作任务列表,创建于ASC
例子:
next_tasks = get_next_tasks()
if next_tasks:
print(f"Next task to work on: {next_tasks[0]['title']}")维护工具
cleaneup_deleted_tasks
永久删除N天前软删除的任务。
参数:
workspace_path(str|None):可选工作区路径days(int):保留天数(默认值:30)
退货: 已清除任务的计数
例子:
# Purge tasks deleted >30 days ago
result = cleanup_deleted_tasks()
print(f"Purged {result['purged_count']} tasks")
# Custom retention period
cleanup_deleted_tasks(days=60)项目管理工具
list_项目
列出主数据库中的所有已知项目。
退货: 按last_accessed DESC排序的项目列表
例子:
projects = list_projects()
for project in projects:
print(f"{project['friendly_name']}: {project['workspace_path']}")get_project_info
获取项目元数据和任务统计信息。
参数:
workspace_path(str,必填):项目工作区路径
退货: 按状态和优先级列出任务计数的项目信息
例子:
info = get_project_info("/path/to/project")
print(f"Total tasks: {info['total_tasks']}")
print(f"By status: {info['by_status']}")
print(f"Blocked: {info['blocked_count']}")set_project_name
为项目设置友好名称。
参数:
workspace_path(str,必填):项目工作区路径friendly_name(str,必填):人类可读的项目名称
退货: 成功确认
例子:
set_project_name("/path/to/project", "My Awesome Project")实体工具
create_entity
创建新实体(文件、供应商或其他类型)。
参数:
entity_type(str,必填):实体类型(“文件”或“其他”)name(str,必填):人类可读的实体名称identifier(str|None):唯一标识符(例如,文件路径、供应商代码)workspace_path(str|None):可选工作区路径(自动检测)description(str|None):实体描述metadata(dict|str|None):通用JSON元数据tags(str|None):空格分隔的标签created_by(str |无):对话ID(自动捕获)
退货: 包含所有字段的实体对象
例子:
# Create vendor entity
vendor = create_entity(
entity_type="other",
name="ABC Insurance Company",
identifier="ABC-INS",
metadata={"phase": "active", "formats": ["xlsx", "pdf"]},
tags="vendor insurance active"
)
# Create file entity
file_entity = create_entity(
entity_type="file",
name="Authentication Controller",
identifier="/src/auth/login.py",
metadata={"language": "python", "line_count": 250},
tags="backend auth"
)update_entity
使用部分更新更新现有实体。
参数:
entity_id(int,必填):实体IDworkspace_path(str|None):可选工作区路径name(str |无):更新名称identifier(str |无):已更新标识符description(str |无):更新描述metadata(dict|str|无):已更新元数据tags(str |无):已更新标签
退货: 已更新实体对象
例子:
# Update vendor metadata
update_entity(
entity_id=1,
metadata={"phase": "inactive", "formats": ["xlsx"]},
tags="vendor insurance inactive"
)get_entity
按ID检索单个实体。
参数:
entity_id(int,必填):实体IDworkspace_path(str|None):可选工作区路径
退货: 包含所有字段的实体对象
例子:
entity = get_entity(entity_id=1)
print(f"{entity['name']}: {entity['entity_type']}")list_entities
列出具有可选过滤功能的实体。
参数:
workspace_path(str|None):可选工作区路径entity_type(str|None):按实体类型(“文件”或“其他”)筛选tags(str|None):按标签筛选(部分匹配)
退货: 实体对象列表
例子:
# Get all vendor entities
vendors = list_entities(entity_type="other", tags="vendor")
# Get all file entities with auth tag
auth_files = list_entities(entity_type="file", tags="auth")删除实体
软删除实体(级联到链接)。
参数:
entity_id(int,必填):实体IDworkspace_path(str|None):可选工作区路径
退货: 成功确认
例子:
delete_entity(entity_id=1)link_entity_to_task
在任务和实体之间创建多对多关系。
参数:
task_id(int,必填):任务IDentity_id(int,必填):实体IDworkspace_path(str|None):可选工作区路径created_by(str |无):对话ID(自动捕获)
退货: 使用Link_id、task_id、entity_id、created_at链接对象
例子:
# Link vendor to commission processing task
link_entity_to_task(task_id=5, entity_id=1)get_task_entities
获取与任务链接的所有实体。
参数:
task_id(int,必填):任务IDworkspace_path(str|None):可选工作区路径
退货: 具有链接元数据的实体对象列表(link_created_at、link_created_by)
例子:
# Get all vendors for a task
entities = get_task_entities(task_id=5)
for entity in entities:
print(f"{entity['name']} ({entity['entity_type']})")
print(f" Linked at: {entity['link_created_at']}")get_entity_tasks
获取链接到实体的所有任务(反向查询)。
参数:
entity_id(int,必填):实体IDworkspace_path(str|None):可选工作区路径status(str|None):按任务状态(todo、in_progress、done等)过滤priority(str|None):按任务优先级(低、中、高)筛选
退货: 带有链接元数据的任务对象列表(link_created_at、link_created_by)
例子:
# Get all tasks for ABC Insurance vendor
tasks = get_entity_tasks(entity_id=7)
for task in tasks:
print(f"{task['title']} - {task['status']}")
print(f" Linked at: {task['link_created_at']}")
# Get only high-priority tasks for a vendor
high_priority_tasks = get_entity_tasks(
entity_id=7,
priority="high"
)
# Get only in-progress tasks for a vendor
in_progress_tasks = get_entity_tasks(
entity_id=7,
status="in_progress"
)示例:供应商实体管理
跟踪保险供应商并将其与佣金处理任务联系起来:
# Create vendor entity
vendor = create_entity(
entity_type="other",
name="ABC Insurance Company",
identifier="ABC-INS",
metadata={"phase": "active", "formats": ["xlsx", "pdf"]},
tags="vendor insurance active"
)
# Create commission processing task
task = create_task(
title="Process ABC Insurance Q4 commissions",
priority="high",
tags="commission q4 vendor"
)
# Link vendor to task
link_entity_to_task(task_id=task["id"], entity_id=vendor["id"])
# Get all vendors for task (forward query)
vendors = get_task_entities(task_id=task["id"])
for v in vendors:
metadata = json.loads(v['metadata'])
print(f"{v['name']}: Phase {metadata['phase']}, Formats: {metadata['formats']}")
# Get all tasks for ABC Insurance vendor (reverse query)
vendor_tasks = get_entity_tasks(entity_id=vendor["id"])
for t in vendor_tasks:
print(f"Task: {t['title']} ({t['status']}) - Priority: {t['priority']}")发展
运行测试
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=task_mcp --cov-report=html
# Run specific test file
uv run pytest tests/test_database.py -v
# Run specific test
uv run pytest tests/test_database.py::TestDatabase::test_get_connection_creates_database质量门
# Linting
uv run ruff check src/ tests/
# Type checking
uv run mypy src/
# Format code
uv run black src/ tests/项目结构
task-mcp/
├── src/task_mcp/
│ ├── __init__.py
│ ├── server.py # FastMCP server + tool registration
│ ├── database.py # Project database operations
│ ├── master.py # Master database (project registry)
│ ├── models.py # Pydantic data models
│ └── utils.py # Utilities (workspace detection, hashing)
├── tests/
│ ├── test_database.py # Database integration tests
│ ├── test_models.py # Model validation tests
│ └── test_mcp_tools.py # MCP tools integration tests
├── pyproject.toml # Project configuration
└── README.md数据库模式
任务表 (tasks):
CREATE TABLE tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT,
status TEXT NOT NULL CHECK(status IN ('todo', 'in_progress', 'blocked', 'done', 'cancelled')),
priority TEXT DEFAULT 'medium' CHECK(priority IN ('low', 'medium', 'high')),
parent_task_id INTEGER,
depends_on TEXT, -- JSON array of task IDs
tags TEXT, -- Space-separated tags
blocker_reason TEXT,
file_references TEXT, -- JSON array of file paths
created_by TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP,
deleted_at TIMESTAMP,
FOREIGN KEY (parent_task_id) REFERENCES tasks(id)
);
-- Indexes
CREATE INDEX idx_status ON tasks(status);
CREATE INDEX idx_parent ON tasks(parent_task_id);
CREATE INDEX idx_deleted ON tasks(deleted_at);
CREATE INDEX idx_tags ON tasks(tags);实体表 (entities):
CREATE TABLE entities (
id INTEGER PRIMARY KEY AUTOINCREMENT,
entity_type TEXT NOT NULL CHECK(entity_type IN ('file', 'other')),
name TEXT NOT NULL,
identifier TEXT,
description TEXT,
metadata TEXT, -- JSON storage for flexible data
tags TEXT, -- Space-separated tags
created_by TEXT, -- Audit: who created
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_by TEXT, -- Audit: who last updated
deleted_at TIMESTAMP
);
-- Indexes
CREATE INDEX idx_entity_type ON entities(entity_type);
CREATE INDEX idx_entity_deleted ON entities(deleted_at);
CREATE INDEX idx_entity_tags ON entities(tags);
CREATE UNIQUE INDEX idx_entity_identifier ON entities(identifier, entity_type)
WHERE deleted_at IS NULL; -- Partial unique index任务实体链接表 (task_entity_links):
CREATE TABLE task_entity_links (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id INTEGER NOT NULL,
entity_id INTEGER NOT NULL,
created_by TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (task_id) REFERENCES tasks(id),
FOREIGN KEY (entity_id) REFERENCES entities(id),
UNIQUE(task_id, entity_id)
);
-- Indexes for bidirectional queries
CREATE INDEX idx_link_task ON task_entity_links(task_id);
CREATE INDEX idx_link_entity ON task_entity_links(entity_id);项目表 (master.db):
CREATE TABLE projects (
id TEXT PRIMARY KEY, -- 8-char hash
workspace_path TEXT UNIQUE NOT NULL,
friendly_name TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_accessed TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_last_accessed ON projects(last_accessed);故障排除
数据库位置
数据库存储在:
- 项目数据库:
~/.task-mcp/databases/project_{hash}.db - 主数据库:
~/.task-mcp/master.db
手动检查:
sqlite3 ~/.task-mcp/master.db "SELECT * FROM projects;"工作区检测问题
检查工作区分辨率优先级:
- 明确的
workspace_path参数(最高优先级) TASK_MCP_WORKSPACE环境变量- 当前工作目录(回退)
验证工作空间检测:
from task_mcp.utils import resolve_workspace
print(resolve_workspace())重置项目数据库
# Find project hash
python -c "from task_mcp.utils import hash_workspace_path; print(hash_workspace_path('/path/to/project'))"
# Remove database
rm ~/.task-mcp/databases/project_{hash}.db许可证
MIT许可证-请参阅许可证文件
贡献
欢迎投稿!拜托:
- 分叉存储库
- 创建要素分支
- 添加新功能的测试
- 确保所有质量门通过(ruff、mypy、pytest)
- 提交拉取请求
致谢
内置:
- FastMCP -MCP服务器框架
- Pydantic v2 -数据验证
- SQLite-嵌入式数据库
