使用说明
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中本地打开:
- 安装 开发容器扩展
- 克隆仓库并在VS Code中打开它
- 出现提示时,单击 在容器中重新打开
一切在 在本地运行 和 部署到Azure 这些部分将在容器内工作,而无需在您的机器上安装任何东西。
注释(代码空间): 每次容器启动时,Azurite都会在后台自动启动。您可以直接进入步骤2 在本地运行.
先决条件
- python 推荐3.12(与部署的函数运行时匹配),支持3.11+本地开发
- Azure功能核心工具 >=
4.0.7030 - Azure开发者命令行界面(
azd) - Azure命令行界面(
az) - Node.js (适用于Azurite本地存储模拟器)
- VS代码+ Azure功能扩展 (可选)
在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参考
- CVE API —
GET /cves/2.0 - CVE历史API —
GET /cvehistory/2.0 - CPE API —
GET /cpes/2.0 - 请求API密钥
- CISA KEV目录 --实时JSON提要
故障排除
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 &
