{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/eugeneyan-com/2025-05-04-building-news-agents-for-daily-news-recaps-with-mcp-q-and/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "To better understand MCPs and agentic workflows, I built news-agents to help me generate a daily news recap. It’s built on [Amazon Q CLI](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line.html) and [MCP](https://modelcontextprotocol.io). The former provides the agentic framework and the latter provides news feeds via tools. It also uses [tmux](https://github.com/tmux/tmux/wiki) to spawn and display each sub-agent’s work. At a high level, here’s how it works:\n\n```markdown\nMain Agent (in the main tmux pane)\n├── Read feeds.txt\n├── Split feeds into 3 chunks\n├── Spawns 3 Sub-Agents (in separate tmux panes)\n│   ├── Sub-Agent #1\n│   │   ├── Process feeds in chunk 1\n│   │   └── Report back when done\n│   ├── Sub-Agent #2\n│   │   ├── Process feeds in chunk 2\n│   │   └── Report back when done\n│   └── Sub-Agent #3\n│       ├── Process feeds in chunk 3\n│       └── Report back when done\n└── Combine everything into main-summary.md\n```\n\nHere, we’ll walk through how the MCP tools are built and how the main agent spawns and monitors sub-agents. Each sub-agent processes its allocated news feeds and generates summaries for each feed. The main agent then combines these summaries into a final summary. Here’s the three-minute 1080p demo (watch till at least 0:30):\n\n[YouTube video player](https://www.youtube.com/watch?v=q41YevguhQw)\n\n## Setting up MCPs for news feeds\n\nEach news feed has its own rss reader, parser, and formatter. These handle the unique structure and format of each feed. (Perhaps in future we can just use an LLM to parse these large text blobs reliably and cheaply.) For example, here’s the code for fetching and parsing the Hacker News rss feed:\n\n```python\nasync def fetch_hn_rss(feed_url: str) -> str:\n    \"\"\"\n    Fetch Hacker News RSS feed.\n\n    Args:\n        feed_url: URL of the RSS feed to fetch (defaults to Hacker News)\n    \"\"\"\n    headers = {\"User-Agent\": USER_AGENT}\n    async with httpx.AsyncClient() as client:\n        try:\n            response = await client.get(feed_url, headers=headers, timeout=10.0)\n            response.raise_for_status()\n            return response.text\n        except httpx.HTTPError as e:\n            return f\"HTTP Error fetching RSS: {str(e)}\"\n        except httpx.TimeoutException:\n            return f\"Timeout fetching RSS from {feed_url}\"\n        except Exception as e:\n            return f\"Error fetching RSS: {str(e)}\"\n\n\ndef parse_hn_rss(rss_content: str) -> List[Dict[str, Any]]:\n    \"\"\"Parse RSS content into a list of story dictionaries.\"\"\"\n    stories = []\n    try:\n        root = ET.fromstring(rss_content)\n        items = root.findall(\".//item\")\n\n        for item in items:\n            story = {\n                \"title\": item.find(\"title\").text\n                if item.find(\"title\") is not None\n                else \"No title\",\n                \"link\": item.find(\"link\").text if item.find(\"link\") is not None else \"\",\n                \"description\": item.find(\"description\").text\n                if item.find(\"description\") is not None\n                else \"No description\",\n                \"pubDate\": item.find(\"pubDate\").text\n                if item.find(\"pubDate\") is not None\n                else \"\",\n                # Any other fields we want to extract\n            }\n            stories.append(story)\n\n        return stories\n    except Exception as e:\n        return [{\"error\": f\"Error parsing RSS: {str(e)}\"}]\n```\n\nThe MCP server then imports these parsers and sets up the MCP tools. MCP makes it easy to set up tools with the `@mcp.tool()` decorator. For example, here’s the Hacker News tool:\n\n```python\n# Initialize FastMCP server\nmcp = FastMCP(\"news-mcp\")\n\n\n@mcp.tool()\nasync def get_hackernews_stories(\n    feed_url: str = DEFAULT_HN_RSS_URL, count: int = 30\n) -> str:\n    \"\"\"Get top stories from Hacker News.\n\n    Args:\n        feed_url: URL of the RSS feed to use (default: Hacker News)\n        count: Number of stories to return (default: 5)\n    \"\"\"\n    rss_content = await fetch_hn_rss(feed_url)\n    if rss_content.startswith(\"Error\"):\n        return rss_content\n\n    stories = parse_hn_rss(rss_content)\n\n    # Limit to requested count\n    stories = stories[: min(count, len(stories))]\n\n    if not stories:\n        return \"No stories found.\"\n\n    formatted_stories = [format_hn_story(story) for story in stories]\n    return \"\\n---\\n\".join(formatted_stories)\n```\n\nWith this, here’s the tools that our agent has from both news-mcp and the built-ins:\n\n```markdown\n> /tools\n\nTool                                          Permission\n▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\nnews_mcp (MCP):\n- news_mcp___get_wired_stories                * not trusted\n- news_mcp___get_techcrunch_stories           * not trusted\n- news_mcp___get_wallstreetjournal_stories    * not trusted\n- news_mcp___get_hackernews_stories           * not trusted\n- news_mcp___get_ainews_latest                * not trusted\n\nBuilt-in:\n- fs_write                                    * not trusted\n- execute_bash                                * trust read-only commands\n- report_issue                                * trusted\n- fs_read                                     * trusted\n- use_aws                                     * trust read-only commands\n```\n\n## Setting up agents to process news\n\nNext, we’ll set up a multi-agent system to parse the news feeds and generate summaries. We’ll have a main agent (image below, top-left) that coordinates three sub-agents, each running in a separate tmux window (image below; bottom-left and right panes).\n\n![The main agent (top-left) with its newly spawned sub-agents](https://eugeneyan.com/assets/news-agents.webp \"The main agent (top-left) with its newly spawned sub-agents\")\n\nThe main agent (top-left) with its newly spawned sub-agents\n\nThe main agent will first divide the news feeds into three groups. Then, it’ll spawn three sub-agents, each assigned to a group of news feeds. In the demo, these sub-agents are displayed as a separate tmux window for each sub-agent.\n\n```markdown\n# Main Agent - Multi-Agent Task Coordinator\n\n## Role\n\nYou are the primary coordinating agent responsible for distributing tasks among \nsub-agents and aggregating their results. \n- Read feeds.txt for the input feeds\n- Read context/sub-agent.md to understand your sub agents\n- Return the summary in the format of context/main-summary-template.md\n\n## Task Assignment Instructions\n\nUse the following message format when assigning tasks: \"You are Agent [NUMBER]. \nRead the instructions at /context/sub-agent.md and execute it. Here are the \nfeeds to process: [FEEDS]\"\n\n...\n```\n\nTruncated instructions for main agent\n\nThen, the sub-agents will process their assigned news feeds and generate summaries for each of them. The sub-agent also categorizes stories within each feed, such as AI/ML, technology, business, etc. Throughout this process, the sub-agents display status updates. When the sub-agent finishes processing its assigned feeds, it displays a final completion status.\n\n```markdown\n# Sub-Agent - Task Processor\n\n## Role\n\nYou are a specialized processing agent designed to execute assigned tasks \nindependently while reporting progress to the main coordinating agent. \nProcess each feed individually and completely before moving to the next one. \nWrite the summaries to summaries/ which has already been created. \nReturn the summary in the format of context/sub-summary-template.md.\n\n...\n```\n\nTruncated instructions for sub-agent\n\nWhile the sub-agents are processing their assigned feeds, the main agent monitors their progress. When all sub-agents are done, the main agent reads the individual feed summaries and combines them into a final summary.\n\n## Defining the news feeds\n\nFinally, we define the news feeds in [feeds.txt](https://github.com/eugeneyan/news-agents/blob/main/feeds.txt) below. We have six feeds: Hacker News, The Wall Street Journal Tech, The Wall Street Journal Markets, TechCrunch, AI News, and Wired.\n\n```markdown\nhackernews: https://news.ycombinator.com/rss\nwsj-tech: https://feeds.content.dowjones.io/public/rss/RSSWSJD\nwsj-markets: https://feeds.content.dowjones.io/public/rss/RSSMarketsMain\ntechcrunch: https://techcrunch.com/feed/\nainews: https://news.smol.ai/rss.xml\nwired: https://www.wired.com/feed/tag/ai/latest/rss\n```\n\nAnd here’s the truncated [main-summary](https://github.com/eugeneyan/news-agents/blob/main/summaries/main-summary.md) it generated for 4th May.\n\n```markdown\n# News for May 4, 2025\n\n### Global Statistics\n- **Total Items Across Sources:** 124\n- **Sources:** 6 (Hacker News, WSJ Tech, WSJ Markets, TechCrunch, AI News, Wired)\n- **Date Range Covered:** May 2-4, 2025\n- **Total Categories Identified:** 42\n\n### Category Distribution\n| Category | Count | Percentage | Top Source |\n|----------|-------|------------|------------|\n| AI/Machine Learning | 31 | 25% | AI News |\n| Business/Finance | 18 | 14.5% | WSJ Markets |\n| Technology | 16 | 12.9% | Hacker News |\n| Politics/Government | 7 | 5.6% | Wired |\n| Cybersecurity/Privacy | 6 | 4.8% | TechCrunch |\n| Trade Policy | 6 | 4.8% | WSJ Markets |\n\n---\n\n## Cross-Source Trends\n\n### Global Top 5 Topics\n\n1. **AI Integration Across Industries**\n   - Mentions across sources: 31\n   - Key sources: AI News, WSJ Tech, TechCrunch, Wired\n   - Representative headlines: \"AI Agents Are Learning How to Collaborate. Companies \n     Need to Work With Them\", \"Agent-to-Agent (A2A) Collaboration\", \"Nvidia CEO Says \n     All Companies Will Need 'AI Factories'\"\n\n2. **Trade Policy and Tariff Impact**\n   - Mentions across sources: 12\n   - Key sources: WSJ Markets, TechCrunch, WSJ Tech\n   - Representative headlines: \"Temu stops shipping products from China to the U.S.\", \n     \"Car Buyers Rushing to Beat Tariffs Find It's Tougher to Get Financing\", \n     \"The Future of Gadgets: Fewer Updates, More Subscriptions, Bigger Price Tags\"\n\n3. **Government AI Implementation**\n   - Mentions across sources: 7\n   - Key sources: Wired, AI News\n   - Representative headlines: \"DOGE Is in Its AI Era\", \"DOGE Put a College Student\n     in Charge of Using AI to Rewrite Regulations\", \"A DOGE Recruiter Is Staffing a\n     Project to Deploy AI Agents Across the US Government\"\n\n4. **AI Safety and Regulation Concerns**\n   - Mentions across sources: 9\n   - Key sources: TechCrunch, WSJ Tech, Wired\n   - Representative headlines: \"One of Google's recent Gemini AI models scores worse on \n     safety\", \"AI chatbots are 'juicing engagement' instead of being useful\", \"Dozens\n     of YouTube Channels Are Showing AI-Generated Cartoon Gore and Fetish Content\"\n\n...\n```\n\nTry it for yourself! Install [Amazon Q CLI](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html) and play with the code here: [news-agents](https://github.com/eugeneyan/news-agents).\n\n```bash\ngit clone https://github.com/eugeneyan/news-agents.git\n\ncd news-agents\nuv sync  # Sync dependencies\nuv tree  # Check httpx and mcp[cli] are installed\n\nq chat --trust-all-tools  # Start Q\n\n/context add --global context/agents.md  # Add system context for multi-agents\n\nQ, read context/main-agent.md and spin up sub agents to execute it.  # Start main agent\n```\n\nInitially, I wanted to host this as a web app, perhaps on a platform like [Daytona](https://www.daytona.io). However, I quickly learned that building remote MCPs isn’t trivial, especially with only a couple of weekend hours to hack on this. For now, I’ll explore applying this setup to other use cases such as parsing design docs and [COEs](https://aws.amazon.com/blogs/mt/why-you-should-develop-a-correction-of-error-coe/), or multi-agent writing and coding workflows. If you’re also experimenting with MCPs or agentic workflows, I’d love to [hear from you](https://x.com/eugeneyan)!\n\nIf you found this useful, please cite this write-up as:\n\n> Yan, Ziyou. (May 2025). Building News Agents for Daily News Recaps with MCP, Q, and tmux. eugeneyan.com. https://eugeneyan.com/writing/news-agents/.\n\nor\n\n```\n@article{yan2025news-agents,\n  title   = {Building News Agents for Daily News Recaps with MCP, Q, and tmux},\n  author  = {Yan, Ziyou},\n  journal = {eugeneyan.com},\n  year    = {2025},\n  month   = {May},\n  url     = {https://eugeneyan.com/writing/news-agents/}\n}\n```\n\nShare on:\n\n![](https://eugeneyan.com/assets/icon-twitter.svg)\n\n![](https://eugeneyan.com/assets/icon-linkedin.svg)\n\n![](https://eugeneyan.com/assets/bluesky.svg)\n\n![](https://eugeneyan.com/assets/icon-facebook.svg)\n\n![](https://eugeneyan.com/assets/icon-mail.svg)\n\nJoin **11,800+** readers getting updates on machine learning, RecSys, LLMs, and engineering.\n",
  "authors": [],
  "captured_at": "2026-09-27T19:29:15.293681927+00:00",
  "category": "programming",
  "content_html": "<p>To better understand MCPs and agentic workflows, I built news-agents to help me generate a daily news recap. It’s built on <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line.html\">Amazon Q CLI</a> and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://modelcontextprotocol.io\">MCP</a>. The former provides the agentic framework and the latter provides news feeds via tools. It also uses <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/tmux/tmux/wiki\">tmux</a> to spawn and display each sub-agent’s work. At a high level, here’s how it works:</p>\n<pre><code class=\"language-markdown\"><span class=\"code-snippet\" data-language=\"Markdown\"><span class=\"syntax-text syntax-html syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-markdown\">Main Agent (in the main tmux pane)\n├── Read feeds.txt\n├── Split feeds into 3 chunks\n├── Spawns 3 Sub-Agents (in separate tmux panes)\n│   ├── Sub-Agent #1\n│   │   ├── Process feeds in chunk 1\n│   │   └── Report back when done\n│   ├── Sub-Agent #2\n│   │   ├── Process feeds in chunk 2\n│   │   └── Report back when done\n│   └── Sub-Agent #3\n│       ├── Process feeds in chunk 3\n│       └── Report back when done\n└── Combine everything into main-summary.md\n</span></span></span></code></pre>\n<p>Here, we’ll walk through how the MCP tools are built and how the main agent spawns and monitors sub-agents. Each sub-agent processes its allocated news feeds and generates summaries for each feed. The main agent then combines these summaries into a final summary. Here’s the three-minute 1080p demo (watch till at least 0:30):</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=q41YevguhQw\">YouTube video player</a></p>\n<h2>Setting up MCPs for news feeds</h2>\n<p>Each news feed has its own rss reader, parser, and formatter. These handle the unique structure and format of each feed. (Perhaps in future we can just use an LLM to parse these large text blobs reliably and cheaply.) For example, here’s the code for fetching and parsing the Hacker News rss feed:</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-modifier syntax-async syntax-python\">async</span> <span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">fetch_hn_rss</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">feed_url</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-annotation syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-parameter syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"> </span><span class=\"syntax-meta syntax-function syntax-annotation syntax-return syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-return syntax-python\">-&gt;</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-comment syntax-block syntax-documentation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-python\">&quot;&quot;&quot;</span>\n    Fetch Hacker News RSS feed.\n\n    Args:\n        feed_url: URL of the RSS feed to fetch (defaults to Hacker News)\n    <span class=\"syntax-punctuation syntax-definition syntax-comment syntax-end syntax-python\">&quot;&quot;&quot;</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">headers</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">User-Agent<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">USER_AGENT</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-with syntax-python\"><span class=\"syntax-storage syntax-modifier syntax-async syntax-python\">async </span><span class=\"syntax-keyword syntax-control syntax-flow syntax-with syntax-python\">with</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">httpx</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">AsyncClient</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-meta syntax-statement syntax-with syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-with syntax-as syntax-python\">as</span></span></span><span class=\"syntax-meta syntax-statement syntax-with syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">client</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-with syntax-python\">:</span></span>\n        <span class=\"syntax-meta syntax-statement syntax-try syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-try syntax-python\">try</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-try syntax-python\">:</span></span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">response</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-keyword syntax-other syntax-await syntax-python\">await</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">client</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">get</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">feed_url</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">headers</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">headers</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">timeout</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">10<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>0</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n            <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">response</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">raise_for_status</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n            <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">response</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span></span>\n        <span class=\"syntax-meta syntax-statement syntax-except syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-except syntax-python\">except</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">httpx</span>.<span class=\"syntax-meta syntax-generic-name syntax-python\">HTTPError</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-as syntax-python\">as</span></span><span class=\"syntax-meta syntax-statement syntax-except syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">e</span></span><span class=\"syntax-meta syntax-statement syntax-except syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-except syntax-python\">:</span></span>\n            <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-storage syntax-type syntax-string syntax-python\">f</span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">HTTP Error fetching RSS: </span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-begin syntax-python\">{</span><span class=\"syntax-source syntax-python syntax-embedded\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">e</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span></span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-end syntax-python\">}</span></span><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n        <span class=\"syntax-meta syntax-statement syntax-except syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-except syntax-python\">except</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">httpx</span>.<span class=\"syntax-meta syntax-generic-name syntax-python\">TimeoutException</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-except syntax-python\">:</span></span>\n            <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-storage syntax-type syntax-string syntax-python\">f</span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Timeout fetching RSS from </span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-begin syntax-python\">{</span><span class=\"syntax-source syntax-python syntax-embedded\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">feed_url</span></span></span></span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-end syntax-python\">}</span></span><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n        <span class=\"syntax-meta syntax-statement syntax-except syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-except syntax-python\">except</span> <span class=\"syntax-support syntax-type syntax-exception syntax-python\">Exception</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-as syntax-python\">as</span></span><span class=\"syntax-meta syntax-statement syntax-except syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">e</span></span><span class=\"syntax-meta syntax-statement syntax-except syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-except syntax-python\">:</span></span>\n            <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-storage syntax-type syntax-string syntax-python\">f</span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Error fetching RSS: </span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-begin syntax-python\">{</span><span class=\"syntax-source syntax-python syntax-embedded\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">e</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span></span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-end syntax-python\">}</span></span><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n\n\n<span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">parse_hn_rss</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">rss_content</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-annotation syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-parameter syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"> </span><span class=\"syntax-meta syntax-function syntax-annotation syntax-return syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-return syntax-python\">-&gt;</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">List</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">Dict</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">Any</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-comment syntax-block syntax-documentation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-python\">&quot;&quot;&quot;</span>Parse RSS content into a list of story dictionaries.<span class=\"syntax-punctuation syntax-definition syntax-comment syntax-end syntax-python\">&quot;&quot;&quot;</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-try syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-try syntax-python\">try</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-try syntax-python\">:</span></span>\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">root</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ET</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">fromstring</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rss_content</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">items</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">root</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">findall</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">.//item<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n        <span class=\"syntax-meta syntax-statement syntax-for syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-python\">for</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">item</span> <span class=\"syntax-meta syntax-statement syntax-for syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-in syntax-python\">in</span></span></span><span class=\"syntax-meta syntax-statement syntax-for syntax-python\"> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">items</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-for syntax-python\">:</span></span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">story</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n                <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">title<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">item</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">find</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">title<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span>\n                <span class=\"syntax-keyword syntax-control syntax-flow syntax-if syntax-inline syntax-python\">if</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">item</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">find</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">title<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">is</span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">not</span> <span class=\"syntax-constant syntax-language syntax-python\">None</span>\n                <span class=\"syntax-keyword syntax-control syntax-flow syntax-else syntax-inline syntax-python\">else</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">No title<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">link<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">item</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">find</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">link<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-if syntax-inline syntax-python\">if</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">item</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">find</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">link<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">is</span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">not</span> <span class=\"syntax-constant syntax-language syntax-python\">None</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-else syntax-inline syntax-python\">else</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">description<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">item</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">find</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">description<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span>\n                <span class=\"syntax-keyword syntax-control syntax-flow syntax-if syntax-inline syntax-python\">if</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">item</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">find</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">description<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">is</span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">not</span> <span class=\"syntax-constant syntax-language syntax-python\">None</span>\n                <span class=\"syntax-keyword syntax-control syntax-flow syntax-else syntax-inline syntax-python\">else</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">No description<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">pubDate<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">item</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">find</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">pubDate<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span>\n                <span class=\"syntax-keyword syntax-control syntax-flow syntax-if syntax-inline syntax-python\">if</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">item</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">find</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">pubDate<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">is</span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">not</span> <span class=\"syntax-constant syntax-language syntax-python\">None</span>\n                <span class=\"syntax-keyword syntax-control syntax-flow syntax-else syntax-inline syntax-python\">else</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span>\n                <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Any other fields we want to extract\n</span>            <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>\n            <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">append</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">story</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-except syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-except syntax-python\">except</span> <span class=\"syntax-support syntax-type syntax-exception syntax-python\">Exception</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-as syntax-python\">as</span></span><span class=\"syntax-meta syntax-statement syntax-except syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">e</span></span><span class=\"syntax-meta syntax-statement syntax-except syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-block syntax-except syntax-python\">:</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">error<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-storage syntax-type syntax-string syntax-python\">f</span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-interpolated syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Error parsing RSS: </span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-begin syntax-python\">{</span><span class=\"syntax-source syntax-python syntax-embedded\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">e</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span></span><span class=\"syntax-meta syntax-interpolation syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-interpolation syntax-end syntax-python\">}</span></span><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>\n</span></span></code></pre>\n<p>The MCP server then imports these parsers and sets up the MCP tools. MCP makes it easy to set up tools with the <code>@mcp.tool()</code> decorator. For example, here’s the Hacker News tool:</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Initialize FastMCP server\n</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mcp</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">FastMCP</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">news-mcp<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n\n<span class=\"syntax-meta syntax-annotation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-annotation syntax-python\">@</span><span class=\"syntax-meta syntax-annotation syntax-function syntax-python\"></span></span><span class=\"syntax-meta syntax-annotation syntax-function syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mcp</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-annotation syntax-function syntax-python\">tool</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-modifier syntax-async syntax-python\">async</span> <span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">get_hackernews_stories</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\">\n    <span class=\"syntax-variable syntax-parameter syntax-python\">feed_url</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-annotation syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-parameter syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span> </span><span class=\"syntax-meta syntax-function syntax-parameters syntax-default-value syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">DEFAULT_HN_RSS_URL</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-parameters syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">count</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-annotation syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-parameter syntax-python\">:</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">int</span></span> </span><span class=\"syntax-meta syntax-function syntax-parameters syntax-default-value syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">30</span>\n</span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"> </span><span class=\"syntax-meta syntax-function syntax-annotation syntax-return syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-return syntax-python\">-&gt;</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-comment syntax-block syntax-documentation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-python\">&quot;&quot;&quot;</span>Get top stories from Hacker News.\n\n    Args:\n        feed_url: URL of the RSS feed to use (default: Hacker News)\n        count: Number of stories to return (default: 5)\n    <span class=\"syntax-punctuation syntax-definition syntax-comment syntax-end syntax-python\">&quot;&quot;&quot;</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rss_content</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-keyword syntax-other syntax-await syntax-python\">await</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">fetch_hn_rss</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">feed_url</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rss_content</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">startswith</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Error<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rss_content</span></span>\n\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">parse_hn_rss</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rss_content</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n    <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Limit to requested count\n</span>    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-punctuation syntax-separator syntax-slice syntax-python\">:</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">min</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">count</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">len</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n\n    <span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">not</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">No stories found.<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">formatted_stories</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">format_hn_story</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">story</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-meta syntax-expression syntax-generator syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-generator syntax-python\">for</span> <span class=\"syntax-meta syntax-generic-name syntax-python\">story</span> <span class=\"syntax-keyword syntax-control syntax-flow syntax-for syntax-in syntax-python\">in</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">stories</span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>\n    <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-constant syntax-character syntax-escape syntax-python\">\\n</span>---<span class=\"syntax-constant syntax-character syntax-escape syntax-python\">\\n</span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">join</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">formatted_stories</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p>With this, here’s the tools that our agent has from both news-mcp and the built-ins:</p>\n<pre><code class=\"language-markdown\"><span class=\"code-snippet\" data-language=\"Markdown\"><span class=\"syntax-text syntax-html syntax-markdown\"><span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-quote syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-blockquote syntax-markdown\">&gt;</span> /tools\n</span></span>\n<span class=\"syntax-meta syntax-paragraph syntax-markdown\">Tool                                          Permission\n▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\nnews_mcp (MCP):\n</span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"> <span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">news_mcp___get_wired_stories                * not trusted\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> news_mcp___get_techcrunch_stories           * not trusted\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> news_mcp___get_wallstreetjournal_stories    * not trusted\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> news_mcp___get_hackernews_stories           * not trusted\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> news_mcp___get_ainews_latest                * not trusted\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">\n</span><span class=\"syntax-meta syntax-paragraph syntax-markdown\">Built-in:\n</span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"> <span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">fs_write                                    * not trusted\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> execute_bash                                * trust read-only commands\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> report_issue                                * trusted\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> fs_read                                     * trusted\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> use_aws                                     * trust read-only commands\n</span></span></span></span></code></pre>\n<h2>Setting up agents to process news</h2>\n<p>Next, we’ll set up a multi-agent system to parse the news feeds and generate summaries. We’ll have a main agent (image below, top-left) that coordinates three sub-agents, each running in a separate tmux window (image below; bottom-left and right panes).</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://eugeneyan.com/assets/news-agents.webp\" alt=\"The main agent (top-left) with its newly spawned sub-agents\" title=\"The main agent (top-left) with its newly spawned sub-agents\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The main agent (top-left) with its newly spawned sub-agents</p>\n<p>The main agent will first divide the news feeds into three groups. Then, it’ll spawn three sub-agents, each assigned to a group of news feeds. In the demo, these sub-agents are displayed as a separate tmux window for each sub-agent.</p>\n<pre><code class=\"language-markdown\"><span class=\"code-snippet\" data-language=\"Markdown\"><span class=\"syntax-text syntax-html syntax-markdown\"><span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-1 syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">#</span> </span><span class=\"syntax-markup syntax-heading syntax-1 syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Main Agent - Multi-Agent Task Coordinator</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span>\n<span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-2 syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">##</span> </span><span class=\"syntax-markup syntax-heading syntax-2 syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Role</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span>\n<span class=\"syntax-meta syntax-paragraph syntax-markdown\">You are the primary coordinating agent responsible for distributing tasks among \nsub-agents and aggregating their results. \n</span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"> <span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">Read feeds.txt for the input feeds\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Read context/sub-agent.md to understand your sub agents\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Return the summary in the format of context/main-summary-template.md\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">\n</span><span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-2 syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">##</span> </span><span class=\"syntax-markup syntax-heading syntax-2 syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Task Assignment Instructions</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span>\n<span class=\"syntax-meta syntax-paragraph syntax-markdown\">Use the following message format when assigning tasks: &quot;You are Agent [NUMBER]. \nRead the instructions at /context/sub-agent.md and execute it. Here are the \nfeeds to process: [FEEDS]&quot;\n\n</span><span class=\"syntax-meta syntax-paragraph syntax-markdown\">...\n</span></span></span></code></pre>\n<p>Truncated instructions for main agent</p>\n<p>Then, the sub-agents will process their assigned news feeds and generate summaries for each of them. The sub-agent also categorizes stories within each feed, such as AI/ML, technology, business, etc. Throughout this process, the sub-agents display status updates. When the sub-agent finishes processing its assigned feeds, it displays a final completion status.</p>\n<pre><code class=\"language-markdown\"><span class=\"code-snippet\" data-language=\"Markdown\"><span class=\"syntax-text syntax-html syntax-markdown\"><span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-1 syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">#</span> </span><span class=\"syntax-markup syntax-heading syntax-1 syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Sub-Agent - Task Processor</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span>\n<span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-2 syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">##</span> </span><span class=\"syntax-markup syntax-heading syntax-2 syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Role</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span>\n<span class=\"syntax-meta syntax-paragraph syntax-markdown\">You are a specialized processing agent designed to execute assigned tasks \nindependently while reporting progress to the main coordinating agent. \nProcess each feed individually and completely before moving to the next one. \nWrite the summaries to summaries/ which has already been created. \nReturn the summary in the format of context/sub-summary-template.md.\n\n</span><span class=\"syntax-meta syntax-paragraph syntax-markdown\">...\n</span></span></span></code></pre>\n<p>Truncated instructions for sub-agent</p>\n<p>While the sub-agents are processing their assigned feeds, the main agent monitors their progress. When all sub-agents are done, the main agent reads the individual feed summaries and combines them into a final summary.</p>\n<h2>Defining the news feeds</h2>\n<p>Finally, we define the news feeds in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/eugeneyan/news-agents/blob/main/feeds.txt\">feeds.txt</a> below. We have six feeds: Hacker News, The Wall Street Journal Tech, The Wall Street Journal Markets, TechCrunch, AI News, and Wired.</p>\n<pre><code class=\"language-markdown\"><span class=\"code-snippet\" data-language=\"Markdown\"><span class=\"syntax-text syntax-html syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-markdown\">hackernews: <span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">https://news.ycombinator.com</span><span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">/rss</span>\nwsj-tech: <span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">https://feeds.content.dowjones.io</span><span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">/public/rss/RSSWSJD</span>\nwsj-markets: <span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">https://feeds.content.dowjones.io</span><span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">/public/rss/RSSMarketsMain</span>\ntechcrunch: <span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">https://techcrunch.com</span><span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">/feed/</span>\nainews: <span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">https://news.smol.ai</span><span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">/rss</span><span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">.</span><span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">xml</span>\nwired: <span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">https://www.wired.com</span><span class=\"syntax-markup syntax-underline syntax-link syntax-markdown\">/feed/tag/ai/latest/rss</span>\n</span></span></span></code></pre>\n<p>And here’s the truncated <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/eugeneyan/news-agents/blob/main/summaries/main-summary.md\">main-summary</a> it generated for 4th May.</p>\n<pre><code class=\"language-markdown\"><span class=\"code-snippet\" data-language=\"Markdown\"><span class=\"syntax-text syntax-html syntax-markdown\"><span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-1 syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">#</span> </span><span class=\"syntax-markup syntax-heading syntax-1 syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">News for May 4, 2025</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span>\n<span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">###</span> </span><span class=\"syntax-markup syntax-heading syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Global Statistics</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"> <span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"><span class=\"syntax-markup syntax-bold syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-bold syntax-begin syntax-markdown\">**</span>Total Items Across Sources:<span class=\"syntax-punctuation syntax-definition syntax-bold syntax-end syntax-markdown\">**</span></span> 124\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> <span class=\"syntax-markup syntax-bold syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-bold syntax-begin syntax-markdown\">**</span>Sources:<span class=\"syntax-punctuation syntax-definition syntax-bold syntax-end syntax-markdown\">**</span></span> 6 (Hacker News, WSJ Tech, WSJ Markets, TechCrunch, AI News, Wired)\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> <span class=\"syntax-markup syntax-bold syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-bold syntax-begin syntax-markdown\">**</span>Date Range Covered:<span class=\"syntax-punctuation syntax-definition syntax-bold syntax-end syntax-markdown\">**</span></span> May 2-4, 2025\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> <span class=\"syntax-markup syntax-bold syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-bold syntax-begin syntax-markdown\">**</span>Total Categories Identified:<span class=\"syntax-punctuation syntax-definition syntax-bold syntax-end syntax-markdown\">**</span></span> 42\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">\n</span><span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">###</span> </span><span class=\"syntax-markup syntax-heading syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Category Distribution</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span><span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-meta syntax-table syntax-header syntax-markdown\"><span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Category <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Count <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Percentage <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Top Source <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span>\n</span><span class=\"syntax-meta syntax-table syntax-header-separator syntax-markdown\"><span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span><span class=\"syntax-punctuation syntax-section syntax-table-header syntax-markdown\">----------</span><span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span><span class=\"syntax-punctuation syntax-section syntax-table-header syntax-markdown\">-------</span><span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span><span class=\"syntax-punctuation syntax-section syntax-table-header syntax-markdown\">------------</span><span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span><span class=\"syntax-punctuation syntax-section syntax-table-header syntax-markdown\">------------</span><span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span>\n</span><span class=\"syntax-meta syntax-table syntax-markdown\"><span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> AI/Machine Learning <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 31 <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 25% <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> AI News <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span>\n<span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Business/Finance <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 18 <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 14.5% <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> WSJ Markets <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span>\n<span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Technology <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 16 <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 12.9% <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Hacker News <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span>\n<span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Politics/Government <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 7 <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 5.6% <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Wired <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span>\n<span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Cybersecurity/Privacy <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 6 <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 4.8% <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> TechCrunch <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span>\n<span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> Trade Policy <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 6 <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> 4.8% <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span> WSJ Markets <span class=\"syntax-punctuation syntax-separator syntax-table-cell syntax-markdown\">|</span>\n</span></span>\n<span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-meta syntax-separator syntax-thematic-break syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-thematic-break syntax-markdown\">---</span>\n</span></span>\n<span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-2 syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">##</span> </span><span class=\"syntax-markup syntax-heading syntax-2 syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Cross-Source Trends</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span>\n<span class=\"syntax-meta syntax-block-level syntax-markdown\"><span class=\"syntax-markup syntax-heading syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-heading syntax-begin syntax-markdown\">###</span> </span><span class=\"syntax-markup syntax-heading syntax-markdown\"><span class=\"syntax-entity syntax-name syntax-section syntax-markdown\">Global Top 5 Topics</span><span class=\"syntax-meta syntax-whitespace syntax-newline syntax-markdown\">\n</span></span></span>\n<span class=\"syntax-markup syntax-list syntax-numbered syntax-bullet syntax-markdown\">1<span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">.</span></span><span class=\"syntax-markup syntax-list syntax-numbered syntax-markdown\"> <span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"><span class=\"syntax-markup syntax-bold syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-bold syntax-begin syntax-markdown\">**</span>AI Integration Across Industries<span class=\"syntax-punctuation syntax-definition syntax-bold syntax-end syntax-markdown\">**</span></span>\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Mentions across sources: 31\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Key sources: AI News, WSJ Tech, TechCrunch, Wired\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Representative headlines: &quot;AI Agents Are Learning How to Collaborate. Companies \n</span></span><span class=\"syntax-markup syntax-list syntax-numbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">     </span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">Need to Work With Them&quot;, &quot;Agent-to-Agent (A2A) Collaboration&quot;, &quot;Nvidia CEO Says \n</span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">     </span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">All Companies Will Need &#39;AI Factories&#39;&quot;\n</span>\n</span><span class=\"syntax-markup syntax-list syntax-numbered syntax-bullet syntax-markdown\">2<span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">.</span></span><span class=\"syntax-markup syntax-list syntax-numbered syntax-markdown\"> <span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"><span class=\"syntax-markup syntax-bold syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-bold syntax-begin syntax-markdown\">**</span>Trade Policy and Tariff Impact<span class=\"syntax-punctuation syntax-definition syntax-bold syntax-end syntax-markdown\">**</span></span>\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Mentions across sources: 12\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Key sources: WSJ Markets, TechCrunch, WSJ Tech\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Representative headlines: &quot;Temu stops shipping products from China to the U.S.&quot;, \n</span></span><span class=\"syntax-markup syntax-list syntax-numbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">     </span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">&quot;Car Buyers Rushing to Beat Tariffs Find It&#39;s Tougher to Get Financing&quot;, \n</span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">     </span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">&quot;The Future of Gadgets: Fewer Updates, More Subscriptions, Bigger Price Tags&quot;\n</span>\n</span><span class=\"syntax-markup syntax-list syntax-numbered syntax-bullet syntax-markdown\">3<span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">.</span></span><span class=\"syntax-markup syntax-list syntax-numbered syntax-markdown\"> <span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"><span class=\"syntax-markup syntax-bold syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-bold syntax-begin syntax-markdown\">**</span>Government AI Implementation<span class=\"syntax-punctuation syntax-definition syntax-bold syntax-end syntax-markdown\">**</span></span>\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Mentions across sources: 7\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Key sources: Wired, AI News\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Representative headlines: &quot;DOGE Is in Its AI Era&quot;, &quot;DOGE Put a College Student\n</span></span><span class=\"syntax-markup syntax-list syntax-numbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">     </span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">in Charge of Using AI to Rewrite Regulations&quot;, &quot;A DOGE Recruiter Is Staffing a\n</span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">     </span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">Project to Deploy AI Agents Across the US Government&quot;\n</span>\n</span><span class=\"syntax-markup syntax-list syntax-numbered syntax-bullet syntax-markdown\">4<span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">.</span></span><span class=\"syntax-markup syntax-list syntax-numbered syntax-markdown\"> <span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"><span class=\"syntax-markup syntax-bold syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-bold syntax-begin syntax-markdown\">**</span>AI Safety and Regulation Concerns<span class=\"syntax-punctuation syntax-definition syntax-bold syntax-end syntax-markdown\">**</span></span>\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Mentions across sources: 9\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Key sources: TechCrunch, WSJ Tech, Wired\n</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\">   </span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-bullet syntax-markdown\"><span class=\"syntax-punctuation syntax-definition syntax-list_item syntax-markdown\">-</span></span><span class=\"syntax-markup syntax-list syntax-unnumbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\"> Representative headlines: &quot;One of Google&#39;s recent Gemini AI models scores worse on \n</span></span><span class=\"syntax-markup syntax-list syntax-numbered syntax-markdown\"><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">     </span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">safety&quot;, &quot;AI chatbots are &#39;juicing engagement&#39; instead of being useful&quot;, &quot;Dozens\n</span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">     </span><span class=\"syntax-meta syntax-paragraph syntax-list syntax-markdown\">of YouTube Channels Are Showing AI-Generated Cartoon Gore and Fetish Content&quot;\n</span>\n</span><span class=\"syntax-meta syntax-paragraph syntax-markdown\">...\n</span></span></span></code></pre>\n<p>Try it for yourself! Install <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html\">Amazon Q CLI</a> and play with the code here: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/eugeneyan/news-agents\">news-agents</a>.</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">git</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> clone https://github.com/eugeneyan/news-agents.git</span>\n\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-cd syntax-shell\">cd</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> news-agents</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">uv</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> sync  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Sync dependencies</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">uv</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> tree  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Check httpx and mcp[cli] are installed</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">q</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> chat<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>trust-all-tools  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Start Q</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">/context</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> add<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>global</span> context/agents.md  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Add system context for multi-agents</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">Q,</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> read context/main-agent.md and spin up sub agents to execute it.  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-shell\">#</span></span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\"> Start main agent</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-shell\">\n</span></span></span></span></code></pre>\n<p>Initially, I wanted to host this as a web app, perhaps on a platform like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.daytona.io\">Daytona</a>. However, I quickly learned that building remote MCPs isn’t trivial, especially with only a couple of weekend hours to hack on this. For now, I’ll explore applying this setup to other use cases such as parsing design docs and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://aws.amazon.com/blogs/mt/why-you-should-develop-a-correction-of-error-coe/\">COEs</a>, or multi-agent writing and coding workflows. If you’re also experimenting with MCPs or agentic workflows, I’d love to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/eugeneyan\">hear from you</a>!</p>\n<p>If you found this useful, please cite this write-up as:</p>\n<blockquote>\n<p>Yan, Ziyou. (May 2025). Building News Agents for Daily News Recaps with MCP, Q, and tmux. eugeneyan.com. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://eugeneyan.com/writing/news-agents/\">https://eugeneyan.com/writing/news-agents/</a>.</p>\n</blockquote>\n<p>or</p>\n<pre><code><span class=\"code-snippet\">@article{yan2025news-agents,\n  title   = {Building News Agents for Daily News Recaps with MCP, Q, and tmux},\n  author  = {Yan, Ziyou},\n  journal = {eugeneyan.com},\n  year    = {2025},\n  month   = {May},\n  url     = {https://eugeneyan.com/writing/news-agents/}\n}\n</span></code></pre>\n<p>Share on:</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://eugeneyan.com/assets/icon-twitter.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://eugeneyan.com/assets/icon-linkedin.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://eugeneyan.com/assets/bluesky.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://eugeneyan.com/assets/icon-facebook.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://eugeneyan.com/assets/icon-mail.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Join <strong>11,800+</strong> readers getting updates on machine learning, RecSys, LLMs, and engineering.</p>\n",
  "content_markdown": "To better understand MCPs and agentic workflows, I built news-agents to help me generate a daily news recap. It’s built on [Amazon Q CLI](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line.html) and [MCP](https://modelcontextprotocol.io). The former provides the agentic framework and the latter provides news feeds via tools. It also uses [tmux](https://github.com/tmux/tmux/wiki) to spawn and display each sub-agent’s work. At a high level, here’s how it works:\n\n```markdown\nMain Agent (in the main tmux pane)\n├── Read feeds.txt\n├── Split feeds into 3 chunks\n├── Spawns 3 Sub-Agents (in separate tmux panes)\n│   ├── Sub-Agent #1\n│   │   ├── Process feeds in chunk 1\n│   │   └── Report back when done\n│   ├── Sub-Agent #2\n│   │   ├── Process feeds in chunk 2\n│   │   └── Report back when done\n│   └── Sub-Agent #3\n│       ├── Process feeds in chunk 3\n│       └── Report back when done\n└── Combine everything into main-summary.md\n```\n\nHere, we’ll walk through how the MCP tools are built and how the main agent spawns and monitors sub-agents. Each sub-agent processes its allocated news feeds and generates summaries for each feed. The main agent then combines these summaries into a final summary. Here’s the three-minute 1080p demo (watch till at least 0:30):\n\n[YouTube video player](https://www.youtube.com/watch?v=q41YevguhQw)\n\n## Setting up MCPs for news feeds\n\nEach news feed has its own rss reader, parser, and formatter. These handle the unique structure and format of each feed. (Perhaps in future we can just use an LLM to parse these large text blobs reliably and cheaply.) For example, here’s the code for fetching and parsing the Hacker News rss feed:\n\n```python\nasync def fetch_hn_rss(feed_url: str) -> str:\n    \"\"\"\n    Fetch Hacker News RSS feed.\n\n    Args:\n        feed_url: URL of the RSS feed to fetch (defaults to Hacker News)\n    \"\"\"\n    headers = {\"User-Agent\": USER_AGENT}\n    async with httpx.AsyncClient() as client:\n        try:\n            response = await client.get(feed_url, headers=headers, timeout=10.0)\n            response.raise_for_status()\n            return response.text\n        except httpx.HTTPError as e:\n            return f\"HTTP Error fetching RSS: {str(e)}\"\n        except httpx.TimeoutException:\n            return f\"Timeout fetching RSS from {feed_url}\"\n        except Exception as e:\n            return f\"Error fetching RSS: {str(e)}\"\n\n\ndef parse_hn_rss(rss_content: str) -> List[Dict[str, Any]]:\n    \"\"\"Parse RSS content into a list of story dictionaries.\"\"\"\n    stories = []\n    try:\n        root = ET.fromstring(rss_content)\n        items = root.findall(\".//item\")\n\n        for item in items:\n            story = {\n                \"title\": item.find(\"title\").text\n                if item.find(\"title\") is not None\n                else \"No title\",\n                \"link\": item.find(\"link\").text if item.find(\"link\") is not None else \"\",\n                \"description\": item.find(\"description\").text\n                if item.find(\"description\") is not None\n                else \"No description\",\n                \"pubDate\": item.find(\"pubDate\").text\n                if item.find(\"pubDate\") is not None\n                else \"\",\n                # Any other fields we want to extract\n            }\n            stories.append(story)\n\n        return stories\n    except Exception as e:\n        return [{\"error\": f\"Error parsing RSS: {str(e)}\"}]\n```\n\nThe MCP server then imports these parsers and sets up the MCP tools. MCP makes it easy to set up tools with the `@mcp.tool()` decorator. For example, here’s the Hacker News tool:\n\n```python\n# Initialize FastMCP server\nmcp = FastMCP(\"news-mcp\")\n\n\n@mcp.tool()\nasync def get_hackernews_stories(\n    feed_url: str = DEFAULT_HN_RSS_URL, count: int = 30\n) -> str:\n    \"\"\"Get top stories from Hacker News.\n\n    Args:\n        feed_url: URL of the RSS feed to use (default: Hacker News)\n        count: Number of stories to return (default: 5)\n    \"\"\"\n    rss_content = await fetch_hn_rss(feed_url)\n    if rss_content.startswith(\"Error\"):\n        return rss_content\n\n    stories = parse_hn_rss(rss_content)\n\n    # Limit to requested count\n    stories = stories[: min(count, len(stories))]\n\n    if not stories:\n        return \"No stories found.\"\n\n    formatted_stories = [format_hn_story(story) for story in stories]\n    return \"\\n---\\n\".join(formatted_stories)\n```\n\nWith this, here’s the tools that our agent has from both news-mcp and the built-ins:\n\n```markdown\n> /tools\n\nTool                                          Permission\n▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔\nnews_mcp (MCP):\n- news_mcp___get_wired_stories                * not trusted\n- news_mcp___get_techcrunch_stories           * not trusted\n- news_mcp___get_wallstreetjournal_stories    * not trusted\n- news_mcp___get_hackernews_stories           * not trusted\n- news_mcp___get_ainews_latest                * not trusted\n\nBuilt-in:\n- fs_write                                    * not trusted\n- execute_bash                                * trust read-only commands\n- report_issue                                * trusted\n- fs_read                                     * trusted\n- use_aws                                     * trust read-only commands\n```\n\n## Setting up agents to process news\n\nNext, we’ll set up a multi-agent system to parse the news feeds and generate summaries. We’ll have a main agent (image below, top-left) that coordinates three sub-agents, each running in a separate tmux window (image below; bottom-left and right panes).\n\n![The main agent (top-left) with its newly spawned sub-agents](https://eugeneyan.com/assets/news-agents.webp \"The main agent (top-left) with its newly spawned sub-agents\")\n\nThe main agent (top-left) with its newly spawned sub-agents\n\nThe main agent will first divide the news feeds into three groups. Then, it’ll spawn three sub-agents, each assigned to a group of news feeds. In the demo, these sub-agents are displayed as a separate tmux window for each sub-agent.\n\n```markdown\n# Main Agent - Multi-Agent Task Coordinator\n\n## Role\n\nYou are the primary coordinating agent responsible for distributing tasks among \nsub-agents and aggregating their results. \n- Read feeds.txt for the input feeds\n- Read context/sub-agent.md to understand your sub agents\n- Return the summary in the format of context/main-summary-template.md\n\n## Task Assignment Instructions\n\nUse the following message format when assigning tasks: \"You are Agent [NUMBER]. \nRead the instructions at /context/sub-agent.md and execute it. Here are the \nfeeds to process: [FEEDS]\"\n\n...\n```\n\nTruncated instructions for main agent\n\nThen, the sub-agents will process their assigned news feeds and generate summaries for each of them. The sub-agent also categorizes stories within each feed, such as AI/ML, technology, business, etc. Throughout this process, the sub-agents display status updates. When the sub-agent finishes processing its assigned feeds, it displays a final completion status.\n\n```markdown\n# Sub-Agent - Task Processor\n\n## Role\n\nYou are a specialized processing agent designed to execute assigned tasks \nindependently while reporting progress to the main coordinating agent. \nProcess each feed individually and completely before moving to the next one. \nWrite the summaries to summaries/ which has already been created. \nReturn the summary in the format of context/sub-summary-template.md.\n\n...\n```\n\nTruncated instructions for sub-agent\n\nWhile the sub-agents are processing their assigned feeds, the main agent monitors their progress. When all sub-agents are done, the main agent reads the individual feed summaries and combines them into a final summary.\n\n## Defining the news feeds\n\nFinally, we define the news feeds in [feeds.txt](https://github.com/eugeneyan/news-agents/blob/main/feeds.txt) below. We have six feeds: Hacker News, The Wall Street Journal Tech, The Wall Street Journal Markets, TechCrunch, AI News, and Wired.\n\n```markdown\nhackernews: https://news.ycombinator.com/rss\nwsj-tech: https://feeds.content.dowjones.io/public/rss/RSSWSJD\nwsj-markets: https://feeds.content.dowjones.io/public/rss/RSSMarketsMain\ntechcrunch: https://techcrunch.com/feed/\nainews: https://news.smol.ai/rss.xml\nwired: https://www.wired.com/feed/tag/ai/latest/rss\n```\n\nAnd here’s the truncated [main-summary](https://github.com/eugeneyan/news-agents/blob/main/summaries/main-summary.md) it generated for 4th May.\n\n```markdown\n# News for May 4, 2025\n\n### Global Statistics\n- **Total Items Across Sources:** 124\n- **Sources:** 6 (Hacker News, WSJ Tech, WSJ Markets, TechCrunch, AI News, Wired)\n- **Date Range Covered:** May 2-4, 2025\n- **Total Categories Identified:** 42\n\n### Category Distribution\n| Category | Count | Percentage | Top Source |\n|----------|-------|------------|------------|\n| AI/Machine Learning | 31 | 25% | AI News |\n| Business/Finance | 18 | 14.5% | WSJ Markets |\n| Technology | 16 | 12.9% | Hacker News |\n| Politics/Government | 7 | 5.6% | Wired |\n| Cybersecurity/Privacy | 6 | 4.8% | TechCrunch |\n| Trade Policy | 6 | 4.8% | WSJ Markets |\n\n---\n\n## Cross-Source Trends\n\n### Global Top 5 Topics\n\n1. **AI Integration Across Industries**\n   - Mentions across sources: 31\n   - Key sources: AI News, WSJ Tech, TechCrunch, Wired\n   - Representative headlines: \"AI Agents Are Learning How to Collaborate. Companies \n     Need to Work With Them\", \"Agent-to-Agent (A2A) Collaboration\", \"Nvidia CEO Says \n     All Companies Will Need 'AI Factories'\"\n\n2. **Trade Policy and Tariff Impact**\n   - Mentions across sources: 12\n   - Key sources: WSJ Markets, TechCrunch, WSJ Tech\n   - Representative headlines: \"Temu stops shipping products from China to the U.S.\", \n     \"Car Buyers Rushing to Beat Tariffs Find It's Tougher to Get Financing\", \n     \"The Future of Gadgets: Fewer Updates, More Subscriptions, Bigger Price Tags\"\n\n3. **Government AI Implementation**\n   - Mentions across sources: 7\n   - Key sources: Wired, AI News\n   - Representative headlines: \"DOGE Is in Its AI Era\", \"DOGE Put a College Student\n     in Charge of Using AI to Rewrite Regulations\", \"A DOGE Recruiter Is Staffing a\n     Project to Deploy AI Agents Across the US Government\"\n\n4. **AI Safety and Regulation Concerns**\n   - Mentions across sources: 9\n   - Key sources: TechCrunch, WSJ Tech, Wired\n   - Representative headlines: \"One of Google's recent Gemini AI models scores worse on \n     safety\", \"AI chatbots are 'juicing engagement' instead of being useful\", \"Dozens\n     of YouTube Channels Are Showing AI-Generated Cartoon Gore and Fetish Content\"\n\n...\n```\n\nTry it for yourself! Install [Amazon Q CLI](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html) and play with the code here: [news-agents](https://github.com/eugeneyan/news-agents).\n\n```bash\ngit clone https://github.com/eugeneyan/news-agents.git\n\ncd news-agents\nuv sync  # Sync dependencies\nuv tree  # Check httpx and mcp[cli] are installed\n\nq chat --trust-all-tools  # Start Q\n\n/context add --global context/agents.md  # Add system context for multi-agents\n\nQ, read context/main-agent.md and spin up sub agents to execute it.  # Start main agent\n```\n\nInitially, I wanted to host this as a web app, perhaps on a platform like [Daytona](https://www.daytona.io). However, I quickly learned that building remote MCPs isn’t trivial, especially with only a couple of weekend hours to hack on this. For now, I’ll explore applying this setup to other use cases such as parsing design docs and [COEs](https://aws.amazon.com/blogs/mt/why-you-should-develop-a-correction-of-error-coe/), or multi-agent writing and coding workflows. If you’re also experimenting with MCPs or agentic workflows, I’d love to [hear from you](https://x.com/eugeneyan)!\n\nIf you found this useful, please cite this write-up as:\n\n> Yan, Ziyou. (May 2025). Building News Agents for Daily News Recaps with MCP, Q, and tmux. eugeneyan.com. https://eugeneyan.com/writing/news-agents/.\n\nor\n\n```\n@article{yan2025news-agents,\n  title   = {Building News Agents for Daily News Recaps with MCP, Q, and tmux},\n  author  = {Yan, Ziyou},\n  journal = {eugeneyan.com},\n  year    = {2025},\n  month   = {May},\n  url     = {https://eugeneyan.com/writing/news-agents/}\n}\n```\n\nShare on:\n\n![](https://eugeneyan.com/assets/icon-twitter.svg)\n\n![](https://eugeneyan.com/assets/icon-linkedin.svg)\n\n![](https://eugeneyan.com/assets/bluesky.svg)\n\n![](https://eugeneyan.com/assets/icon-facebook.svg)\n\n![](https://eugeneyan.com/assets/icon-mail.svg)\n\nJoin **11,800+** readers getting updates on machine learning, RecSys, LLMs, and engineering.\n",
  "dateCreated": "2026-09-27T19:29:15.293681927+00:00",
  "date_created": "2025-05-04T00:00:00+00:00",
  "date_modified": "2025-05-04T00:00:00+00:00",
  "date_published": "2025-05-04T00:00:00+00:00",
  "description": "Learning to automate simple agentic workflows with Amazon Q CLI, Anthropic MCP, and tmux.",
  "external_url": "https://eugeneyan.com//writing/news-agents/",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/eugeneyan-com/2025/05/2025-05-04-building-news-agents-for-daily-news-recaps-with-mcp-q-and.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/eugeneyan-com/2025/05/2025-05-04-building-news-agents-for-daily-news-recaps-with-mcp-q-and.md"
  },
  "id": "urn:aggr:item:3134124baeb646c6b0fac69b95979ec4d384f682",
  "isBasedOn": {
    "@id": "https://eugeneyan.com//writing/news-agents/"
  },
  "mainEntity": {
    "@id": "https://eugeneyan.com//writing/news-agents/",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/eugeneyan-com/2025-05-04-building-news-agents-for-daily-news-recaps-with-mcp-q-and/#webpage"
    },
    "dateModified": "2025-05-04T00:00:00+00:00",
    "datePublished": "2025-05-04T00:00:00+00:00",
    "headline": "Building News Agents for Daily News Recaps with MCP, Q, and tmux",
    "timeRequired": "PT7M",
    "url": "https://eugeneyan.com//writing/news-agents/",
    "wordCount": 1530
  },
  "name": "Archived snapshot: Building News Agents for Daily News Recaps with MCP, Q, and tmux",
  "preview": null,
  "reading_minutes": 7,
  "replicated_at": null,
  "source": "eugeneyan-com",
  "source_name": "Eugene Yan",
  "summary": "Learning to automate simple agentic workflows with Amazon Q CLI, Anthropic MCP, and tmux.",
  "tags": [
    "learning",
    "llm",
    "🛠"
  ],
  "temporalCoverage": "2026-09-27T19:29:15.293681927+00:00",
  "title": "Building News Agents for Daily News Recaps with MCP, Q, and tmux",
  "url": "https://aggr.aymericbeaumet.com/items/eugeneyan-com/2025-05-04-building-news-agents-for-daily-news-recaps-with-mcp-q-and/",
  "word_count": 1530
}