漏洞数据库MCP服务器

一个远程MCP服务器,将NIST国家漏洞数据库(NVD)的REST API暴露为AI可调用的工具,构建于Azure Functions上。

  • by KnowledgeRatio
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 KnowledgeRatio/nvd-mcp-func

使用说明

NVD MCP服务器——Azure函数(Python)

遥控器 MCP(模型上下文协议) 暴露的服务器 NIST国家漏洞数据库(NVD) API作为AI可调用工具。基于Azure Functions和Python构建,通过以下方式部署 azd.

NVD API密钥是 可选的 --服务器在没有一个的情况下以较低的速率限制工作(5个请求/30s未经身份验证vs 50个请求/3os经过身份验证)。获取免费钥匙 nvd.nist.gov/developers/request-a-pai-key.


可用的MCP工具

工具 说明
search_cves 按关键字、严重性、CWE、CPE、日期范围、KEV成员资格等搜索CVE数据库
get_cve 检索特定CVE的完整详细信息(CVSS评分、受影响的配置、参考)
get_cve_history 获取CVE记录的NVD更改历史记录——显示分数、状态或分析何时更新
search_cves_by_cpe 通过CPE 2.3名称查找影响特定产品的所有CVE
get_recent_cves 获取过去N天内发布的CVE,可根据严重性或KEV状态进行筛选
search_cpes 按名称搜索CPE产品条目——使用此项查找其他工具的确切CPE URI
get_kev 通过关键字/日期/勒索软件过滤实时获取CISA已知漏洞目录

快速入门-GitHub代码空间(零本地安装)

该仓库包含一个预配置的开发容器,其中自动安装了所有工具(Python、azd、az、func、Node、Azurite、MCP Inspector)。

或者在VS Code中本地打开:

  1. 安装 开发容器扩展
  2. 克隆仓库并在VS Code中打开它
  3. 出现提示时,单击 在容器中重新打开

一切在 在本地运行 和 部署到Azure 这些部分将在容器内工作,而无需在您的机器上安装任何东西。

注释(代码空间): 每次容器启动时,Azurite都会在后台自动启动。您可以直接进入步骤2 在本地运行.


先决条件

在macOS上安装必备组件

最简单的方法是通过 家酿:

# Install Homebrew if you don't have it
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install tools
brew install azure-developer-cli
brew install azure-cli
brew tap azure/functions
brew install azure-functions-core-tools@4
brew install node

在Windows上安装必备组件

winget install Microsoft.Azd
winget install Microsoft.AzureCLI
winget install OpenJS.NodeJS.LTS
npm install -g azure-functions-core-tools@4 --unsafe-perm true

在本地运行

1.启动存储模拟器

Azurite在本地模拟Azure存储,是Functions主机所必需的。

npx azurite --location ~/.azurite --silent

在单独的终端选项卡中保持此运行状态。

代码空间: Azurite已经在运行了——跳过这一步。

2.创建虚拟环境并安装依赖项

Python worker解析来自 .venv 内部文件夹 src/.

cd src
python -m venv .venv

安装依赖项:

# macOS / Linux
.venv/bin/pip install -r requirements.txt

# Windows (PowerShell)
.venv\Scripts\pip install -r requirements.txt

验证安装是否成功:

# macOS / Linux
.venv/bin/python -c "import azure.functions; print('OK')"

# Windows
.venv\Scripts\python -c "import azure.functions; print('OK')"

预期产量: OK

3.配置本地设置

# macOS / Linux
cp src/local.settings.json.example src/local.settings.json

# Windows PowerShell
Copy-Item src\local.settings.json.example src\local.settings.json

编辑 src/local.settings.json 并可选择填写您的NVD API密钥:

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "PYTHON_ISOLATE_WORKER_DEPENDENCIES": "1",
    "NVD_API_KEY": "<your-key-or-leave-empty>"
  }
}

注: local.settings.json 是合法的,永远不会被承诺。

4.启动Functions主机

cd src
func start

等待,直到您看到类似于以下内容的输出:

Azure Functions Core Tools
...
Functions:
        search_cves: [POST,GET] http://localhost:7071/runtime/webhooks/mcp
        get_cve: [POST,GET] http://localhost:7071/runtime/webhooks/mcp
        ...
Host lock lease acquired by instance ID ...

MCP服务器现在可以在 http://localhost:7071/runtime/webhooks/mcp.

故障排除: 如果 func start 由于存储错误而失败,请确保Azurite正在运行(步骤1)。如果它因导入错误而失败,请确保将依赖项安装到 src/.venv (步骤2)。


从客户端连接

VS代码--GitHub复制品代理模式

打开 .vscode/mcp.json。单击 开始 上方 local-mcp-function 服务器入口。然后问Copilot:

Search for critical CVEs related to log4j
Get the full details for CVE-2021-44228
What CVEs have been added to the KEV catalog in the last 30 days?

MCP检查员

npx @modelcontextprotocol/inspector

将运输设置为 Streamable HTTP,URL到 http://localhost:7071/runtime/webhooks/mcp,然后单击 连接.


部署到Azure

1.登录Azure

azd auth login

同时使用Azure CLI登录(某些部署后步骤需要):

az login

2.创造一个azd环境

azd env new <your-environment-name>

3.设置所需的环境变量

# Required: choose a supported region (see infra/main.bicep for the full allowed list)
azd env set AZURE_LOCATION <region>   # e.g. uksouth, swedencentral, eastus

# Required: set to true to deploy with VNet + private endpoints, false for public access
azd env set VNET_ENABLED false

之前只选择一种身份验证模式 azd up:

模式 要设置的环境变量 行为
基于密钥(默认) 无 MCP webhook使用功能系统密钥认证
Entra(EasyAuth) azd env set ENTRA_AUTH_ENABLED true 预提供钩子创建/重用应用程序注册和设置 ENTRA_APP_CLIENT_ID;webhook身份验证委托给EasyAuth
未经身份验证(仅限开发人员) azd env set MCP_UNAUTHENTICATED_ACCESS true MCP webhook无需身份验证即可公开访问

不要同时设置这两个 ENTRA_AUTH_ENABLED=true 和 MCP_UNAUTHENTICATED_ACCESS=true如果两者都设置,则预提供挂钩将优先处理未经身份验证的访问。

快速验证:

azd env get-values

多个订阅? 如果您的帐户有多个订阅,请同时运行:

azd env set AZURE_SUBSCRIPTION_ID <your-subscription-id>

4.(可选)设置您的NVD API密钥

azd env set NVD_API_KEY <your-key>

如果跳过此步骤,服务器将在未经身份验证的情况下针对NVD(较低的NVD速率限制)进行部署和工作。您可以稍后添加密钥。

5.部署

azd up

这提供了一个资源组,其中包含:

  • Azure Functions应用程序(灵活消费计划)
  • Azure密钥保管库(存储NVD API密钥(如果提供))
  • Azure存储帐户
  • 应用洞察+日志分析工作区
  • 用户分配的托管身份

如果 VNET_ENABLED=true,功能应用程序公共网络访问被禁用,MCP端点只能从专用网络访问。

当部署完成时, azd up 打印MCP端点URL:

Outputs:
  MCP_ENDPOINT: https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp

6.连接到远程MCP服务器

您的端点格式:

https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp

基于密钥的模式(默认)

获取系统密钥:

az functionapp keys list \
  --name <function-app-name> \
  --resource-group <resource-group> \
  --query "systemKeys.mcp_extension" -o tsv

在VS Code中,单击 开始 上 remote-mcp-function 在 .vscode/mcp.json 并提供功能应用名称+系统密钥。

进入模式ENTRA_AUTH_ENABLED=true)

使用承载令牌作为作用域 api://<ENTRA_APP_CLIENT_ID>/user_impersonation 而不是 x-functions-key.

az account get-access-token \
  --scope "api://<ENTRA_APP_CLIENT_ID>/user_impersonation" \
  --query accessToken -o tsv

配置您的MCP客户端以发送:

Authorization: Bearer <access-token>

未验证模式(MCP_UNAUTHENTICATED_ACCESS=true)

不需要身份验证标头。仅用于孤立的开发场景。

部署后更新NVD API密钥

az keyvault secret set \
  --vault-name <keyvault-name> \
  --name NVD-API-KEY \
  --value <new-key>

功能应用程序在下次调用时自动解析密钥库引用(最多缓存约24小时;重新启动应用程序以立即生效)。

此命令需要RBAC权限才能写入密钥库机密(例如, Key Vault Secrets Officer).当前模板默认为最小权限,不会自动将此角色分配给部署用户。


秘密管理

上下文 密钥的存储方式
本地 src/local.settings.json (忽略)
Azure Azure密钥库密钥;Function App在运行时使用用户分配的托管身份通过密钥库引用读取它——原始密钥永远不会出现在应用程序配置中
部署 azd env set NVD_API_KEY <key> 写信给 .azure/*/env.json (根忽略了 .gitignore,但在您的计算机上仍为明文)

有用的命令

# Redeploy code without reprovisioning infrastructure
azd deploy

# View live function logs
az webapp log tail --name <funcappname> --resource-group <rg>

# Tear down all Azure resources
azd down

MCP工具参考

下面的每个工具都记录了其参数并给出了示例提示。当通过AI助手(例如GitHub Copilot)使用时,AI会选择合适的工具并根据对话填写参数。


search_cves

使用灵活的过滤器搜索NVD CVE数据库。返回与CVSS分数、描述、引用和元数据匹配的漏洞。

参数

参数 类型 必填 说明
keyword string 否 在CVE描述和标题中搜索的关键字(例如。 log4j, remote code execution)
cve_id string 否 特定CVE标识符(例如。 CVE-2021-44228).提供时,其他过滤器将被忽略
cpe_name string No CPE 2.3名称,用于过滤特定产品的CVE(例如。 cpe:2.3:a:apache:log4j:*)
cvss_v3_severity string 否 按CVSS v3严重性筛选: LOW, MEDIUM, HIGH,或 CRITICAL
cwe_id string 否 按CWE标识符筛选(例如。 CWE-79 对于XSS)
pub_start_date string 否 ISO 8601格式的发布开始日期(例如。 2024-01-01T00:00:00.000).最大范围:120天
pub_end_date string 否 ISO 8601格式的发布结束日期。最大范围:120天
last_mod_start_date string 否 ISO 8601格式的上次修改开始日期。最大范围:120天
last_mod_end_date string 否 ISO 8601格式的最后修改结束日期。最大范围:120天
has_kev boolean 否 何时 true,仅返回CISA已知漏洞目录中的CVE
results_per_page integer 否 每页结果(1-2000)。违约: 20
start_index integer 否 分页索引为零。违约: 0

示例提示

Search for critical CVEs related to log4j
Find all XSS vulnerabilities (CWE-79) published this year
Show me HIGH severity CVEs that are in the KEV catalog
Search for CVEs affecting Apache HTTP Server published between 2024-01-01 and 2024-03-31

get_cve

通过标识符检索单个CVE的完整记录。返回CVSS v2和v3得分、弱点数据(CWE)、受影响的产品配置(CPE)、参考链接和当前状态。

参数

参数 类型 必填 说明
cve_id 字符串 是 CVE标识符(例如。 CVE-2021-44228)

示例提示

Get the full details for CVE-2021-44228
What is the CVSS score and description for CVE-2023-44487?
Show me all affected products for CVE-2024-3094

get_cve_history

检索CVE记录的NVD更改历史记录。在最初分析漏洞、修改分数或状态更改为“已拒绝”时,可用于审计。

参数

参数 类型 必填 说明
cve_id string 否 检索特定CVE的历史记录。留空,按日期范围查询
change_start_date string 否 ISO 8601格式的更改事件日期范围的开始。最大范围:120天
change_end_date string 否 ISO 8601格式的更改事件日期范围的结束。最大范围:120天
event_name string 否 按事件类型筛选: Initial Analysis, Reanalysis, CVE Modified, CVE Rejected, CVE Translated
results_per_page integer 否 每页结果(1-5000)。违约: 20
start_index integer 否 分页索引为零。违约: 0

注: 您必须提供 cve_id 或日期范围(change_start_date + change_end_date).提供两者都不返回API错误。

示例提示

Show the change history for CVE-2021-44228
What CVE records were modified in the NVD last week?
List all CVEs that were rejected between 2024-01-01 and 2024-03-31
When was CVE-2023-44487 first analysed?

search_cves_by_cpe

使用CPE 2.3名称查找影响特定产品的所有CVE。使用 search_cpes 首先发现确切的CPE URI。

参数

参数 类型 必填 说明
cpe_name 字符串 是 CPE 2.3名称(例如。 cpe:2.3:a:apache:log4j:2.14.1:*:*:*:*:*:*:*)
results_per_page integer 否 每页结果(1-2000)。违约: 20
start_index integer 否 分页索引为零。违约: 0

示例提示

Find all CVEs for Apache Log4j 2.14.1
What vulnerabilities affect OpenSSL 3.0?

get_recent_cves

获取最近N天内发布的CVE。查看已披露的新漏洞的快速方法,可选择按严重程度或KEV状态进行过滤。

参数

参数 类型 必填 说明
days integer 否 回溯多少天(1-120)。违约: 7
cvss_v3_severity string 否 按CVSS v3严重性筛选: LOW, MEDIUM, HIGH,或 CRITICAL
has_kev boolean 否 何时 true,仅返回CISA KEV目录中的CVE
results_per_page integer 否 每页结果(1-2000)。违约: 20
start_index integer 否 分页索引为零。违约: 0

示例提示

What critical CVEs were published in the last 7 days?
Show me new HIGH or CRITICAL vulnerabilities from the past 30 days
What recently published CVEs are already in the KEV catalog?
Give me a summary of this week's new vulnerabilities

search_cpes

在NVD CPE(通用平台枚举)词典中搜索产品条目。使用此功能查找以下内容所需的确切CPE 2.3 URI search_cves_by_cpe 或 cpe_name 筛选 search_cves.

参数

参数 类型 必填 说明
keyword string 否 产品名称或供应商关键字(例如。 apache tomcat, openssl)
cpe_match_string string 否 要匹配的部分CPE 2.3字符串(例如。 cpe:2.3:a:microsoft)
results_per_page integer 否 每页结果(1-10000)。违约: 20
start_index integer 否 分页索引为零。违约: 0

示例提示

Find the CPE name for Apache Tomcat 10
What is the exact CPE identifier for OpenSSL 3.1.0?
Search for all Microsoft products in the CPE dictionary

get_kev

实时获取CISA已知利用漏洞(KEV)目录。KEV目录列出了已知在野外被积极利用的漏洞,这些漏洞受CISA约束的操作指令BOD 22-01的约束。

参数

参数 类型 必填 说明
keyword string 否 按供应商、产品或漏洞名称筛选(不区分大小写)
since string 否 仅返回在此日期或之后添加到KEV的条目(YYYY-MM-DD)
ransomware_only boolean 否 何时 true,仅返回与已知勒索软件活动关联的条目
results_per_page integer 否 要返回的最大条目数(1-2000)。违约: 10

示例提示

What are the most recently added entries to the CISA KEV catalog?
Show me KEV entries added since 2024-01-01
Which KEV vulnerabilities are associated with ransomware campaigns?
Are there any Citrix products in the KEV catalog?

源代码

文件 目的
src/function_app.py MCP工具定义(search_cves, get_cve, get_cve_history, search_cves_by_cpe, get_recent_cves, search_cpes, get_kev)
src/nvd-service.py NVD REST API客户端和CISA KEV目录提取器
基础设施/主要设施 Azure基础架构(功能、密钥库、存储、监控)
infra/app/keyvault.bicep 密钥库资源和RBAC角色分配

NVD API参考


故障排除

func start 失败,出现“Microsoft.Azure.Storage.Common”或与存储相关的错误

Azurite没有运行。在单独的终端中启动它:

npx azurite --location ~/.azurite --silent

func start 失败,返回“ModuleNotFoundError:没有名为'azure.functions'的模块”

依赖项未安装到 src/.venv.运行:

cd src
python -m venv .venv
.venv/bin/pip install -r requirements.txt   # macOS/Linux
# or
.venv\Scripts\pip install -r requirements.txt   # Windows

NVD API返回403或速率限制错误

在没有API密钥的情况下,NVD API每30秒窗口允许5个请求。将您的密钥添加到 src/local.settings.json (本地)或运行 azd env set NVD_API_KEY <key> 在部署之前。

azd up 失败,显示“VNET_ENABLED未设置”

此变量是必需的。在部署之前设置它:

azd env set VNET_ENABLED false   # public access
# or
azd env set VNET_ENABLED true    # private/VNet-only access

部署后无法更新密钥保管库中的NVD API密钥

默认情况下,模板不会向部署用户授予 Key Vault Secrets Officer 角色(最低权限)。要启用密钥更新,请手动分配角色:

KV=$(az keyvault list --resource-group <rg> --query "[0].name" -o tsv)
az role assignment create \
  --role "Key Vault Secrets Officer" \
  --assignee <your-user-object-id> \
  --scope $(az keyvault show --name $KV --query id -o tsv)

然后设置秘密:

az keyvault secret set --vault-name $KV --name NVD-API-KEY --value <new-key>

MCP客户端显示本地服务器的“连接被拒绝”

确保 func start 正在7071端口上运行和侦听。检查你跑步的终点站 func start 对于错误。

Devcontainer/Codespace:Azurite在容器重启后未运行

Azurite配置为通过以下方式自动启动 postStartCommand。如果它没有运行,请手动启动:

nohup npx azurite --location ~/.azurite --silent > ~/.azurite/azurite.log 2>&1 &