fix(mcp): list tools return rows that say what a record is, not what it says (#4061)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Successful in 49s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Successful in 1m31s
CI & Build / Build & push image (push) Successful in 22s
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 8s
CI & Build / integration (push) Successful in 49s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Successful in 1m31s
CI & Build / Build & push image (push) Successful in 22s
list_tasks returned every row's to_dict(), body included: a project's todo list came to 93-165k characters, past what an MCP client accepts inline, so the list arrived as a file to page through (the #4045 failure, one call over). - notes.brief_row: id, title, type, project, tags, updated_at; for tasks, status, kind, priority, milestone id and title; description, parent and due date only when set. - milestones.titles_for: one query for the milestone titles a page of rows names. - Brief rows on list_tasks, list_notes, get_milestone's steps, get_system and list_system_records. get_task / get_note / get_snippet read a record in full, and each docstring says so. - tests/test_list_rows_brief.py pins the ceiling: 100 rows of ~5k-character step plans stay under 40k characters. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
This commit is contained in:
@@ -22,6 +22,7 @@ from scribe.mcp._context import current_user_id
|
||||
from scribe.mcp.tools import systems as systems_tools
|
||||
from scribe.services import access as access_svc
|
||||
from scribe.services import dedup as dedup_svc
|
||||
from scribe.services import milestones as milestones_svc
|
||||
from scribe.services import notes as notes_svc
|
||||
# Imported by NAME, not reached through notes_svc: minted_kind is pure
|
||||
# validation, not a service call, and a test that stubs the service module to
|
||||
@@ -58,7 +59,10 @@ async def list_tasks(
|
||||
kind: Filter by task kind — 'work', 'issue', 'spike' (or the retired
|
||||
'plan'). Omit (empty) for all kinds.
|
||||
|
||||
Results are ordered by last-updated descending.
|
||||
Results are ordered by last-updated descending. Each row says what the task
|
||||
is and where it sits — id, title, status, kind, priority, milestone (id and
|
||||
title), tags, updated_at, plus description, parent and due date when set —
|
||||
and not what it says: read one in full with get_task(id).
|
||||
"""
|
||||
uid = current_user_id()
|
||||
rows, total = await notes_svc.list_notes(
|
||||
@@ -70,7 +74,8 @@ async def list_tasks(
|
||||
limit=max(1, min(limit, 100)),
|
||||
offset=max(0, offset),
|
||||
)
|
||||
return {"tasks": [n.to_dict() for n in rows], "total": total}
|
||||
titles = await milestones_svc.titles_for({n.milestone_id for n in rows})
|
||||
return {"tasks": [notes_svc.brief_row(n, titles) for n in rows], "total": total}
|
||||
|
||||
|
||||
async def get_task(task_id: int) -> dict:
|
||||
|
||||
Reference in New Issue
Block a user