feat(fable-mcp): implement FableClient, all tool modules, and server.py
- client.py: async httpx wrapper, FableAPIError, stream_get() SSE generator, singleton init_client()/get_client() and _reset_client() for tests - tools/: notes, tasks, projects, milestones, search, chat — thin async functions that accept FableClient and call Fable REST endpoints - server.py: FastMCP entry point with 20 tools registered via @mcp.tool(), each opening a fresh FableClient context per call; validates env vars at startup - tests: 34 tests covering client HTTP behaviour, error handling, singleton, SSE streaming, and all tool modules Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
"""MCP tool for semantic search across Fable notes and tasks."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fable_mcp.client import FableClient
|
||||
|
||||
|
||||
async def search(
|
||||
client: FableClient,
|
||||
*,
|
||||
q: str,
|
||||
content_type: str = "all",
|
||||
limit: int = 10,
|
||||
) -> dict[str, Any]:
|
||||
"""Semantic search over notes and/or tasks.
|
||||
|
||||
Args:
|
||||
q: Search query string.
|
||||
content_type: One of "note", "task", or "all" (default).
|
||||
limit: Maximum number of results to return.
|
||||
|
||||
Returns:
|
||||
Dict with "results" list and "total" count.
|
||||
Each result has: id, title, body, is_task, tags, similarity.
|
||||
"""
|
||||
params: dict[str, Any] = {"q": q, "limit": limit}
|
||||
if content_type != "all":
|
||||
params["content_type"] = content_type
|
||||
return await client.get("/api/search", params=params)
|
||||
Reference in New Issue
Block a user