RSS聚合服务

基于Azure Functions的远程MCP服务器,用于实时动态处理RSS订阅源并与AI集成。

  • by artcava
  • Bicep
  • 本地部署
  • 更新于
在 GitHub 查看 artcava/MCPFeeder

使用说明

MCPFeeder:使用Azure函数(.NET/C#)进行RSS源聚合的远程MCP服务器

MCPFeeder已准备好投入生产 模型上下文协议(MCP)服务器 建立在 Azure 函数 它使AI代理(如GitHub Copilot)能够动态获取和处理 RSS源 实时从多个来源获取。此快速入门模板允许您在几分钟内构建、在本地进行完整调试测试,并将自定义MCP服务器部署到云端。

服务器是 通过设计确保安全 使用API密钥和HTTPS,通过EasyAuth、API管理策略对OAuth提供额外支持,以及使用VNET的可选网络隔离。

MCPFeeder的主要特点

RSS源处理工具(get_feeds)

MCPFeeder提供的核心MCP工具:

  • 动态饲料获取:从作为参数传递的任何URL检索RSS提要内容
  • 时间滤波:自动从中提取提要项 过去24小时 (前一天午夜至当天午夜)
  • 智能高速缓存:使用内存缓存 24小时TTL 优化性能并减少外部HTTP调用
  • 稳健解析:
    • 处理具有适当命名空间支持的标准RSS XML格式
    • 摘录:标题、内容、链接和发布日期
    • 自动清除描述中的HTML标签
    • 解码HTML实体以获得干净的内容
  • 错误处理:优雅的降级,并显示信息丰富的错误消息(没有向客户端抛出异常)
  • 超时保护:HTTP请求超时15秒以防止挂起
  • 测井和观测:用于调试和监控的完整Application Insights集成

工具调用示例

Tool Name: get_feeds
Description: Feeds data from a specified URL.

Parameter: Url (required)
Description: The URL to fetch data from.

Example:
  Input:  https://example.com/feed.xml
  Output: [Yesterday's feed items with title, content, link, and publish date]

观看视频概述

如果您正在寻找其他语言的此示例,请查看 Node.js/TypeScript 和 python 样品。

先决条件

所有开发方法都需要:

对于Visual Studio开发:

对于Visual Studio代码开发:

选择一个:您可以使用Visual Studio或Visual Studio代码。两者都提供完整的调试支持,但设置步骤略有不同。

架构概述

以下是使用Azure Functions的MCPFeeder远程MCP服务器的架构图:

组件体系结构

MCPFeeder实现了 分层架构 专门针对RSS提要处理进行了优化:

层 组件 责任
客户端层 MCP客户端(VS代码、副本、MCP检查器) 发送HTTP请求以获取提要
运输 HTTP/HTTPS协议 通过系统密钥身份验证进行安全通信
运行时 Azure Functions Worker(.NET 8独立版) 无服务器计算平台
MCP协议 MCP服务器 路由工具调用和管理协议
工具层 FeederTool.FeedUrl() 暴露 get_feeds 作为MCP工具
业务逻辑 FeedService.GetFeedsAsync() RSS解析、过滤和缓存
缓存层 IMemoryCache(进程中) 馈送数据的24小时TTL
外部集成 HTTP客户端到源URL 从远程源获取RSS源

请求响应流

┌─────────────────────────────────────────────────────────────┐
│ MCP Client (Copilot, MCP Inspector, Custom Tools)         │
│ Request: tool/call "get_feeds" with URL parameter         │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ HTTPS Request to Azure Functions                           │
│ POST /runtime/webhooks/mcp?code=<system_key>             │
│ Content: JSON-RPC 2.0 tool invocation                     │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ Azure Functions Worker (Runtime)                           │
│ .NET 8 Isolated Worker Process                           │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ MCP Server                                                  │
│ Routes to: FeederTool.FeedUrl()                           │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ FeederTool.FeedUrl()                                        │
│ • Validates URL parameter                                  │
│ • Calculates date range (last 24 hours)                   │
│ • Calls FeedService.GetFeedsAsync()                       │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ FeedService.GetFeedsAsync()                                 │
│ Step 1: Check Memory Cache (24hr TTL)                     │
│         ✓ Cache Hit → Return cached feeds                │
│         ✗ Cache Miss → Proceed to step 2                 │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ HTTP Client (15s timeout)                                  │
│ Fetches RSS feed from provided URL                        │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ XML Parser                                                  │
│ • Parse RSS XML document                                   │
│ • Extract items with pubDate, title, description, link    │
│ • Filter items by date (last 24 hours only)              │
│ • Clean HTML tags from descriptions                       │
│ • Decode HTML entities                                    │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ Memory Cache                                                │
│ Save parsed RSSFeed objects with 24-hour TTL              │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ Return Response                                             │
│ Formatted text: [Title]\n[Content]\n[Link]\n[Date]\n\n... │
│ Or error message if parsing failed                         │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ JSON-RPC 2.0 Response                                       │
│ Returns to MCP Client (Copilot) with tool output          │
└──────────────────────┬──────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────┐
│ MCP Client Processing                                       │
│ Integrates feed data into AI context for analysis          │
│ Can use for summarization, recommendations, etc.          │
└─────────────────────────────────────────────────────────────┘

数据模型

每个RSS提要项都表示为 RSSFeed 记录:

public record RSSFeed
{
    public required string Title { get; init; }           // Article headline
    public required string Content { get; init; }         // Cleaned description (no HTML)
    public required string Link { get; init; }            // URL to full article
    public DateTimeOffset PublishDate { get; init; }      // Publication timestamp
}

缓存策略

  • 钥匙: feeds_{url}_{startDate:yyyyMMdd}_{endDate:yyyyMMdd}
  • 生存时间:24小时
  • 命中率:在同一天内查询同一URL时优化请求
  • 存储:进程内存(随函数实例缩放)

安全架构

  • 认证:Azure Functions系统密钥(默认)
  • 运输:仅在生产环境中使用HTTPS
  • 授权:通过EasyAuth或API管理的可选OAuth
  • 网络:用于私有连接的可选VNET隔离
  • 监控:Application Insights中的完整审计跟踪

准备好当地环境

需要Azure存储模拟器进行测试:

  1. 启动Azurite(基于Docker的存储模拟器):

    docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 \
        mcr.microsoft.com/azure-storage/azurite
    

备注:如果您从VS Code扩展中使用Azurite,请运行 Azurite: Start 命令,否则您可能会看到连接错误。

在本地运行MCP服务器

选择您喜欢的开发环境:

选项A:使用Visual Studio代码

从终端运行

  1. 从 src 文件夹,在本地启动Functions主机:

    cd src
    func start
    

服务器将在以下位置可用: /runtime/webhooks/mcp 上 http://localhost:7071

注意:部署到Azure时,您将使用与系统密钥相同的路由: /runtime/webhooks/mcp?code=<system_key>

选项B:使用Visual Studio

  1. 打开 MCPFeeder.sln Visual Studio 2022
  2. 集 MCPFeeder 作为启动项目
  3. 按 F5 开始调试
  4. Function主机将启动并监听 http://localhost:7071/runtime/webhooks/mcp

连接到您的 本地 客户端工具中的MCP服务器

一旦您的Azure Functions MCP服务器在本地运行,您就可以从各种MCP客户端工具进行连接:

在GitHub Copilot上使用VS代码

  1. 添加MCP服务器 从命令选项板(Ctrl+Shift+P → “添加MCP服务器”)

  2. 输入URL: http://localhost:7071/runtime/webhooks/mcp

  3. 列出MCP服务器 从命令面板启动服务器

  4. 在Copilot聊天代理模式下,输入提示以调用该工具。示例提示:

    Get the latest news from https://feeds.bloomberg.com/markets/news.rss
    
    Fetch tech news from https://feeds.arstechnica.com/arstechnica/index
    
    Retrieve yesterday's feeds from https://example.com/rss.xml and summarize them
    
  5. 当系统提示运行该工具时,单击 继续

  6. 要停止服务器,请按 Ctrl+C 在终端

使用MCP检查器(高级测试)

MCP Inspector是一个基于网络的工具,用于测试MCP服务器:

  1. 在一个 新终端窗口,安装并运行MCP检查器:

    npx @modelcontextprotocol/inspector
    
  2. 打开工具显示的URL(例如。, http://0.0.0.0:5173)

  3. 将运输类型设置为 流式HTTP

  4. 输入URL: http://0.0.0.0:7071/runtime/webhooks/mcp (或 http://localhost:7071/runtime/webhooks/mcp/sse 对于Visual Studio)

  5. 点击 连接

  6. 点击 列出工具 查看可用工具

  7. 选择 获取饲料,输入提要URL,然后单击 运行工具

测试 get_feeds 本地工具

用于测试的RSS源URL示例:

  • 彭博市场: https://feeds.bloomberg.com/markets/news.rss
  • ArsTechnica: https://feeds.arstechnica.com/arstechnica/index
  • HN顶部: https://news.ycombinator.com/rss
  • BBC新闻: http://feeds.bbc.co.uk/news/rss.xml
  • 黑客新闻搜索: https://hnrss.org/newest

本地开发故障排除

问题:尝试连接到MCP服务器时连接被拒绝

  • 解决方案:确保Azurite正在运行:
    docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 mcr.microsoft.com/azure-storage/azurite
    

问题:错误的URL(0.0.0.0与本地主机)

  • 解决方案:使用 http://0.0.0.0:7071/runtime/webhooks/mcp 对于VS码, http://localhost:7071/runtime/webhooks/mcp/sse 对于Visual Studio

问题:Visual Studio F5不工作

  • 解决方案:确保已安装Azure开发工作负载,并 MCPFeeder 项目设置为启动项目

问题:Feed返回“在指定的URL和时间范围内找不到提要”

  • 解决方案:这意味着RSS提要已成功获取,但没有昨天的项目。请尝试使用其他提要URL,或检查您的系统日期/时间是否正确。

问题:获取提要时发生超时错误

  • 解决方案:有些饲料可能很慢。该工具有15秒的超时时间。如果提要始终超时,请考虑将其添加到块列表中或增加超时时间(需要修改代码)。

部署到Azure以实现远程MCP

提供和部署

运行以下命令 雅匝德 命令来配置所有必需的Azure资源并部署代码:

az login
azd up

这将:

  • 创建资源组
  • 提供Azure功能应用程序(.NET隔离运行时)
  • 为可选blob存储创建存储帐户
  • 设置应用程序洞察以进行监控
  • 将代码部署到云端

可选:启用Direct3D隔离

为了提高网络隔离的安全性:

azd env set VNET_ENABLED true
azd up

这将在具有受限访问权限的专用虚拟网络中创建您的MCP服务器。

可选:添加API管理

对于高级安全策略和速率限制,请集成API管理:

azd env set APIM_ENABLED true
azd up

看 API与MCP管理 了解更多详情。

连接到您的 远程 来自客户端的MCP服务器

您的客户端需要系统密钥来调用远程MCP端点: https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp

获取您的系统密钥

检索 mcp_extension 系统密钥使用:

选项1:Azure门户

  1. 在Azure门户中打开功能应用程序
  2. 导航至 函数 → 应用程序密钥
  3. 复制 mcp扩展 键值

选项2:Azure CLI

az functionapp keys list --resource-group <resource-group-name> --name <function-app-name>

查找带有描述的钥匙 mcp_extension.

连接MCP检查器

在URL中包含密钥:

https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp?code=<your-mcp-extension-system-key>

连接VS代码-GitHub Copilot

对于VS Code中的Copilot,将密钥设置为 mcp.json。配置文件已在存储库中:

{
    "inputs": [
        {
            "type": "promptString",
            "id": "functions-mcp-extension-system-key",
            "description": "Azure Functions MCP Extension System Key",
            "password": true
        },
        {
            "type": "promptString",
            "id": "functionapp-name",
            "description": "Azure Functions App Name"
        }
    ],
    "servers": {
        "remote-mcp-function": {
            "type": "http",
            "url": "https://${input:functionapp-name}.azurewebsites.net/runtime/webhooks/mcp",
            "headers": {
                "x-functions-key": "${input:functions-mcp-extension-system-key}"
            }
        },
        "local-mcp-function": {
            "type": "http",
            "url": "http://0.0.0.0:7071/runtime/webhooks/mcp"
        }
    }
}

当您单击时 开始 在服务器上,VS Code将提示您输入功能应用程序名称和系统密钥。

重新部署代码

更改后,使用以下命令重新部署:

azd up

您可以根据需要多次运行此命令。它将:

  1. 构建更新后的代码
  2. 上传部署包
  3. 使用最新版本更新您的Function App

[!注意] 部署的代码文件总是被最新的部署包覆盖。

清理资源

完成后,删除所有资源以避免产生费用:

azd down

源代码结构

主要组件

src/Tools/FeederTool.cs -核心MCP工具

[Function(nameof(FeedUrl))]
public async Task<string> FeedUrl(
    [McpToolTrigger("get_feeds", "Feeds data from a specified URL.")] 
    ToolInvocationContext context,
    [McpToolProperty("Url", "The URL to fetch data from.")] 
    string url)
{
    // Fetch feeds for the last 24 hours
    // Returns formatted text with title, content, link, and date
}

src/Services/FeedService.cs -RSS源处理逻辑

  • GetFeedsAsync(url, start, end):获取并解析RSS源
  • 采用24小时TTL实现智能缓存
  • 按日期范围筛选提要
  • 清理HTML并解码实体
  • 优雅地处理错误

src/Models/RSSFeed.cs -数据模型

public record RSSFeed
{
    public required string Title { get; init; }
    public required string Content { get; init; }
    public required string Link { get; init; }
    public DateTimeOffset PublishDate { get; init; }
}

src/Program.cs -依赖注入和配置

  • 配置Azure函数运行时
  • 寄存器 FeedService 作为一种暂时的依赖
  • 启用应用程序洞察遥测

基础设施

infra/main.bicep -基础设施即代码

  • 定义Azure资源(功能应用、存储、应用洞察)
  • 支持可选的ExpressRoute隔离
  • 支持可选的API管理集成

MCPFeeder.sln -Visual Studio解决方案

  • 引用所有项目及其依赖关系

扩展MCPFeeder

添加更多MCP工具

  1. 在中创建新文件 src/Tools/ (例如。, WebScraperTool.cs)
  2. 定义一个函数 [Function] 和 [McpToolTrigger] 属性
  3. 在中注册依赖关系 Program.cs 如有需要
  4. 将工具定义添加到 src/Tools/ToolsDefinitions.cs

加强饲料加工

  • 添加饲料过滤:按类别、关键字或情感筛选
  • 扩展日期范围:使其可配置,而不是硬编码“最后24小时”
  • 支持Atom提要:除了RSS
  • 添加源注册表:维护一个经过审查的提要URL列表

提高性能

  • 使用分布式缓存:用Azure cache for Redis替换内存缓存
  • 实施速率限制:防止滥用端点
  • 添加提要优先级:首先处理流行的订阅源

添加安全功能

  • URL验证:允许订阅源域的白名单
  • 请求签名:实现HMAC-SHA256签名
  • 饲料验证:在处理之前验证RSS架构

安全注意事项

  • API密钥:默认情况下需要系统密钥;考虑为OAuth添加EasyAuth
  • 仅限HTTPS:在生产环境中始终使用HTTPS
  • 速率限制:在API管理中实施以防止滥用
  • Direct3D隔离:使用 VNET_ENABLED=true 用于网络隔离
  • URL验证:考虑阻止对内部/私有IP范围的请求
  • 超时保护:内置15秒超时防止挂起请求

监控和记录

MCPFeeder与 Azure应用洞察 为了实现完全的可观察性:

# View logs in Azure Portal
Azure Portal → Your Function App → Monitoring → Logs

# Or use Azure CLI
az monitor app-insights query --app <app-insights-name> --analytics-query "traces | where message contains 'FeedUrl'"

关键记录点:

  • Feed获取请求和URL
  • 缓存命中/未命中
  • 解析错误
  • 饲料含量统计

技术栈

  • .NET 8.0:现代高性能运行时
  • Azure 函数:Azure上的无服务器计算
  • C:类型安全、功能丰富的语言
  • Bicep:Azure的基础架构即代码
  • 应用洞察:云原生监控
  • Azure存储:可选持久层

许可证

该项目根据MIT许可证获得许可。看 许可证.md 了解详情。

贡献

欢迎投稿!请看 贡献.md 作为指导方针。

相关资源

后续步骤

  1. 部署到Azure:运行 azd up 将服务器置于云中
  2. 使用Copilot进行测试:连接您的VS Code实例并使用 get_feeds 工具
  3. 添加更多工具:按照以下步骤实施其他MCP工具 FeederTool 模式
  4. 使用API管理确保安全:添加速率限制和请求验证策略
  5. 使用App Insights进行监控:跟踪Azure门户中的使用情况和性能

支持

对于问题或疑问: