218f946e48
The MCP tool was sending {"body": ...} but the task logs API route
expects {"content": ...}, causing 400 errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
94 lines
2.6 KiB
Python
94 lines
2.6 KiB
Python
"""MCP tools for Fable tasks."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from fable_mcp.client import FableClient
|
|
|
|
|
|
async def list_tasks(
|
|
client: FableClient,
|
|
*,
|
|
limit: int = 20,
|
|
offset: int = 0,
|
|
status: str | None = None,
|
|
project_id: int | None = None,
|
|
) -> dict[str, Any]:
|
|
"""List tasks with optional filtering."""
|
|
params: dict[str, Any] = {"limit": limit, "offset": offset}
|
|
if status:
|
|
params["status"] = status
|
|
if project_id is not None:
|
|
params["project_id"] = project_id
|
|
return await client.get("/api/tasks", params=params)
|
|
|
|
|
|
async def get_task(client: FableClient, *, task_id: int) -> dict[str, Any]:
|
|
"""Fetch a single task by ID (includes parent_title)."""
|
|
return await client.get(f"/api/tasks/{task_id}")
|
|
|
|
|
|
async def create_task(
|
|
client: FableClient,
|
|
*,
|
|
title: str,
|
|
body: str = "",
|
|
status: str = "todo",
|
|
priority: str | None = None,
|
|
project_id: int | None = None,
|
|
milestone_id: int | None = None,
|
|
parent_id: int | None = None,
|
|
tags: list[str] | None = None,
|
|
) -> dict[str, Any]:
|
|
"""Create a new task."""
|
|
payload: dict[str, Any] = {"title": title, "body": body, "status": status}
|
|
if priority is not None:
|
|
payload["priority"] = priority
|
|
if project_id is not None:
|
|
payload["project_id"] = project_id
|
|
if milestone_id is not None:
|
|
payload["milestone_id"] = milestone_id
|
|
if parent_id is not None:
|
|
payload["parent_id"] = parent_id
|
|
if tags is not None:
|
|
payload["tags"] = tags
|
|
return await client.post("/api/tasks", json=payload)
|
|
|
|
|
|
async def update_task(
|
|
client: FableClient,
|
|
*,
|
|
task_id: int,
|
|
title: str | None = None,
|
|
body: str | None = None,
|
|
status: str | None = None,
|
|
priority: str | None = None,
|
|
project_id: int | None = None,
|
|
milestone_id: int | None = None,
|
|
) -> dict[str, Any]:
|
|
"""Update an existing task."""
|
|
payload: dict[str, Any] = {}
|
|
if title is not None:
|
|
payload["title"] = title
|
|
if body is not None:
|
|
payload["body"] = body
|
|
if status is not None:
|
|
payload["status"] = status
|
|
if priority is not None:
|
|
payload["priority"] = priority
|
|
if project_id is not None:
|
|
payload["project_id"] = project_id
|
|
if milestone_id is not None:
|
|
payload["milestone_id"] = milestone_id
|
|
return await client.patch(f"/api/tasks/{task_id}", json=payload)
|
|
|
|
|
|
async def add_task_log(
|
|
client: FableClient,
|
|
*,
|
|
task_id: int,
|
|
content: str,
|
|
) -> dict[str, Any]:
|
|
"""Append a log entry to a task."""
|
|
return await client.post(f"/api/tasks/{task_id}/logs", json={"content": content})
|