feat(fable-mcp): add RSS feed management tools (list/add/remove)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 10:48:57 -04:00
parent 5f6107bbf8
commit 940dd0c08e
2 changed files with 74 additions and 1 deletions
+42 -1
View File
@@ -5,7 +5,7 @@ from mcp.server.fastmcp import FastMCP
from dotenv import load_dotenv
from fable_mcp.client import FableClient
from fable_mcp.tools import notes, tasks, projects, milestones, search, chat, admin
from fable_mcp.tools import notes, tasks, projects, milestones, search, chat, admin, briefing
load_dotenv()
@@ -366,6 +366,47 @@ async def fable_get_app_logs(
)
# ---------------------------------------------------------------------------
# Briefing / RSS
# ---------------------------------------------------------------------------
@mcp.tool()
async def fable_list_rss_feeds() -> dict:
"""List all RSS feeds configured in Fable for the current user."""
async with FableClient() as client:
return await briefing.list_rss_feeds(client)
@mcp.tool()
async def fable_add_rss_feed(
url: str,
title: str = "",
category: str = "",
) -> dict:
"""Add a new RSS feed to Fable. Title is optional — auto-populated from feed metadata.
Args:
url: The RSS/Atom feed URL.
title: Optional display name override.
category: Optional category label (e.g. 'news', 'tech').
"""
async with FableClient() as client:
return await briefing.add_rss_feed(
client,
url=url,
title=title or None,
category=category or None,
)
@mcp.tool()
async def fable_remove_rss_feed(feed_id: int) -> dict:
"""Remove an RSS feed from Fable by its ID."""
async with FableClient() as client:
return await briefing.remove_rss_feed(client, feed_id=feed_id)
# ---------------------------------------------------------------------------
# Entry point
# ---------------------------------------------------------------------------
+32
View File
@@ -0,0 +1,32 @@
"""MCP tools for Fable RSS feed management."""
from __future__ import annotations
from typing import Any
from fable_mcp.client import FableClient
async def list_rss_feeds(client: FableClient) -> dict[str, Any]:
"""List the user's RSS feeds."""
return await client.get("/api/briefing/feeds")
async def add_rss_feed(
client: FableClient,
*,
url: str,
title: str | None = None,
category: str | None = None,
) -> dict[str, Any]:
"""Add a new RSS feed. Title is optional — auto-populated from feed metadata."""
payload: dict[str, Any] = {"url": url}
if title:
payload["title"] = title
if category:
payload["category"] = category
return await client.post("/api/briefing/feeds", json=payload)
async def remove_rss_feed(client: FableClient, *, feed_id: int) -> dict[str, Any]:
"""Remove an RSS feed by ID."""
return await client.delete(f"/api/briefing/feeds/{feed_id}")