Commit Graph
3 Commits
Author SHA1 Message Date
bvandeusenandClaude Opus 4.7 d086c9b606 feat(mcp): task CRUD tools + add_task_log
Five tools wrapping services/notes.py with is_task=True (tasks are
notes with non-null status) plus services/task_logs.create_log for
add_task_log. Matches existing fable-mcp contracts. No delete_task —
preserves existing surface; cancel by updating status to "cancelled".

fable_get_task enriches with parent_title (extra service call when
parent_id is set), matching the existing route's behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 20:22:30 -04:00
bvandeusenandClaude Opus 4.7 b026421985 feat(mcp): note CRUD tools (list/get/create/update/delete)
Five tools wrapping services/notes.py with is_task=False. Signatures
mirror the existing fable-mcp note tool contracts so Claude usage is
unchanged.

Key behavior the tests pin down:
  - list_notes repackages (rows, total) tuple into {notes, total}
  - tag=""/search_text="" are "no filter" sentinels
  - update_note ONLY sends non-default fields to the service (the
    main risk: a default empty string overwriting real data)
  - tags=[] is an explicit clear; tags=None is "leave unchanged"
  - project_id=0 on create => orphan; on update => leave unchanged
    (preserved limitation from existing fable-mcp)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 20:20:27 -04:00
bvandeusenandClaude Opus 4.7 fd0431dfb6 feat(mcp): tools/ package + fable_search
Establishes the tool pattern: each tool module exposes register(mcp),
register_all() aggregates them, build_mcp_server() calls register_all.

fable_search mirrors the existing fable-mcp contract (q/content_type/limit
in; {results, total} out) but calls services.embeddings.semantic_search_notes
directly instead of going over HTTP. User comes from mcp.current_user_id().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 20:18:36 -04:00