A remote MCP (Model Context Protocol) server that exposes the NIST National Vulnerability Database (NVD) APIs as AI-callable tools. Built on Azure Functions with Python, deployed via azd.
The NVD API key is optional — the server works without one at a lower rate limit (5 req/30s unauthenticated vs 50 req/30s authenticated). Get a free key at nvd.nist.gov/developers/request-an-api-key.
| Tool | Description |
|---|---|
search_cves |
Search the CVE database by keyword, severity, CWE, CPE, date ranges, KEV membership, and more |
get_cve |
Retrieve full details for a specific CVE (CVSS scores, affected configurations, references) |
get_cve_history |
Get the change history for CVEs, filterable by date range and event type |
The repo includes a pre-configured dev container that has all tools installed automatically (Python, azd, az, func, Node, Azurite, MCP Inspector).
Or open locally in VS Code:
- Install the Dev Containers extension
- Clone the repo and open it in VS Code
- When prompted, click Reopen in Container
Everything in the Run locally and Deploy to Azure sections will work inside the container without installing anything on your machine.
- Python 3.11 or higher
- Azure Functions Core Tools >=
4.0.7030 - Azure Developer CLI (
azd) - Azure CLI (
az) - Node.js (for Azurite local storage emulator)
- VS Code + Azure Functions extension (optional)
The easiest way is via Homebrew:
# 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 nodewinget install Microsoft.Azd
winget install Microsoft.AzureCLI
npm install -g azure-functions-core-tools@4 --unsafe-perm truenpx azurite --location ~/.azurite --silentcd src
python -m venv .venv
# Windows
.venv\Scripts\pip install -r requirements.txt
# macOS / Linux
.venv/bin/pip install -r requirements.txtcp src/local.settings.json.example src/local.settings.jsonEdit src/local.settings.json and optionally fill in your NVD API key:
{
"IsEncrypted": false,
"Values": {
"FUNCTIONS_WORKER_RUNTIME": "python",
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"PYTHON_ISOLATE_WORKER_DEPENDENCIES": "1",
"NVD_API_KEY": "<your-key-or-leave-empty>"
}
}Note:
local.settings.jsonis gitignored and will never be committed.
cd src
func startThe MCP server will be available at http://localhost:7071/runtime/webhooks/mcp.
Open .vscode/mcp.json. Click Start above the local-mcp-function server entry. Then ask Copilot:
Search for critical CVEs related to log4j
Get the full details for CVE-2021-44228
npx @modelcontextprotocol/inspectorSet transport to Streamable HTTP, URL to http://localhost:7071/runtime/webhooks/mcp, and click Connect.
azd auth loginazd env new <your-environment-name># 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 falseMultiple subscriptions? If your account has more than one subscription, also run:
azd env set AZURE_SUBSCRIPTION_ID <your-subscription-id>
azd env set NVD_API_KEY <your-key>If you skip this step, the server deploys and works unauthenticated. You can add the key later.
azd upThis provisions a resource group containing:
- Azure Functions app (Flex Consumption plan)
- Azure Key Vault (stores the NVD API key if provided)
- Azure Storage account
- Application Insights + Log Analytics workspace
- User-assigned managed identity
Get the system key for your deployed endpoint:
az functionapp keys list \
--name <function-app-name> \
--resource-group <resource-group> \
--query "systemKeys.mcp_extension" -o tsvYour endpoint: https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp
In VS Code, click Start on the remote-mcp-function entry in .vscode/mcp.json — it will prompt for the function app name and system key.
az keyvault secret set \
--vault-name <keyvault-name> \
--name NVD-API-KEY \
--value <new-key>The Function App resolves the Key Vault reference automatically on next invocation (cached up to ~24h; restart the app for immediate effect).
| Context | How the key is stored |
|---|---|
| Local | src/local.settings.json (gitignored) |
| Azure | Azure Key Vault secret; Function App reads it at runtime via a Key Vault reference using a user-assigned managed identity — the raw key never appears in app configuration |
| Deploy | azd env set NVD_API_KEY <key> writes to .azure/*/env.json (gitignored by root .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| File | Purpose |
|---|---|
| src/function_app.py | MCP tool definitions (search_cves, get_cve, get_cve_history) |
| src/nvd_service.py | NVD REST API client |
| infra/main.bicep | Azure infrastructure (Functions, Key Vault, Storage, Monitoring) |
| infra/app/keyvault.bicep | Key Vault resource and RBAC role assignments |
- CVE API —
GET /cves/2.0 - CVE History API —
GET /cvehistory/2.0 - Request an API key