Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion authors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -591,4 +591,8 @@ sophiaqin-openai:
PASFIELD-OAI:
name: "Wesley Pasfield"
website: "https://github.com/PASFIELD-OAI"
avatar: "https://avatars.githubusercontent.com/u/276116382?v=4"
avatar: "https://avatars.githubusercontent.com/u/276116382?v=4"
ripper:
name: "Ripper"
website: "https://github.com/RipperMercs"
avatar: "https://avatars.githubusercontent.com/u/268111110"
242 changes: 242 additions & 0 deletions examples/mcp/tensorfeed_cve_verification.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cross-Database CVE Verification with TensorFeed (Hosted MCP)\n",
"\n",
"**A common production failure mode for security agents isn't hallucination. It's acting on a single source.**\n",
"\n",
"When a finance agent reads a fabricated headline and trades on it, the model didn't hallucinate; it read the source faithfully and the source was wrong. The same shape applies to security: a triage agent that judges a CVE off one database can be wrong without ever fabricating anything. Corroborating across independent sources narrows that failure class. It does not make the model immune to misreading a record or conflating two CVE ids, so treat the pattern below as risk reduction with an auditable trail, not a guarantee.\n",
"\n",
"This notebook builds a small agent that uses [TensorFeed.ai](https://tensorfeed.ai)'s hosted MCP server with the **OpenAI Responses API's native MCP tool integration** to compose three independent vulnerability databases (MITRE CVE List, CISA Known Exploited Vulnerabilities, FIRST.org EPSS) for any CVE, in a single Responses call.\n",
"\n",
"**Why TensorFeed?** TF is a free hosted MCP server (`https://tensorfeed.ai/api/mcp`) that exposes 17 tools spanning AI news, model pricing, AI service status, security advisories, SEC EDGAR filings, FDA regulatory data, and US energy indicators. No auth is required for the tools used here. TF is also published as a hosted server in the official Model Context Protocol Registry as `ai.tensorfeed/mcp-server`.\n",
"\n",
"**Data licensing (verify each at its source).** The three databases composed here carry different terms, so they are listed individually rather than bundled:\n",
"\n",
"- **MITRE CVE List**: free to search, download, redistribute, and reference provided records are not modified; MITRE-copyrighted to keep it an open standard. [CVE Program Terms of Use](https://www.cve.org/Legal/TermsOfUse)\n",
"- **CISA KEV**: public domain dedication under CC0 1.0; free for any use including commercial. [CISA KEV license](https://www.cisa.gov/sites/default/files/licenses/kev/license.txt)\n",
"- **FIRST.org EPSS**: FIRST grants free public use including commercial use; attribution is requested but not required; this is not a CC0 or public-domain release. [FIRST.org EPSS](https://www.first.org/epss/)\n",
"\n",
"TensorFeed passes these records through unmodified and preserves source attribution on every response. A reader depending on this in production should confirm each term at the linked source.\n",
"\n",
"**Why OpenAI's Responses API for this?** The Responses API supports MCP tools natively (`tools[].type = \"mcp\"`). The model autonomously fans out tool calls, parses results, and composes a final answer in one Responses call. No manual loop required.\n",
"\n",
"**What you'll see by the end:**\n",
"- A single Responses call that verifies one CVE across three security databases via the TF MCP server\n",
"- The `confirmed_by` corroboration pattern surfaced from the model's natural reasoning\n",
"- A second example doing parallel triage of three CVEs ranked by composite risk\n",
"- The actual MCP tool-call trail, so the corroboration is auditable and not taken on faith"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Prerequisites\n",
"\n",
"- Python 3.11+\n",
"- An OpenAI API key in the `OPENAI_API_KEY` environment variable\n",
"- The `openai` package (>= the version that supports Responses API MCP tools)\n",
"\n",
"```bash\n",
"pip install --upgrade openai\n",
"```\n",
"\n",
"No TensorFeed account or API key needed. The three tools used in this notebook are part of TensorFeed's free tier.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from openai import OpenAI\n",
"\n",
"api_key = os.environ.get(\"OPENAI_API_KEY\")\n",
"if not api_key:\n",
" raise RuntimeError(\"Set OPENAI_API_KEY in your environment first.\")\n",
"\n",
"client = OpenAI(api_key=api_key)\n",
"MODEL = \"gpt-5.1\" # any current chat-completions/responses-capable model\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Connect the TensorFeed MCP server as a tool\n",
"\n",
"The Responses API takes the MCP server URL directly. The model decides which tools to call based on the user input plus the descriptions the MCP server returns from `tools/list`. The next cell registers the TF server and scopes it to three tools.\n",
"\n",
"> **Security note (read this before reusing the pattern).**\n",
">\n",
"> `allowed_tools` is an explicit allowlist, not just a focus aid. TF exposes 17 tools; this notebook needs 3, so it grants 3. Least privilege is the default you want for any MCP server: the model can only call what you list, which bounds the blast radius if a prompt is adversarial or the server is later compromised.\n",
">\n",
"> `require_approval: \"never\"` is acceptable **here** because the TensorFeed MCP server is read-only and serves public data (no writes, no account state, no side effects). Cookbook patterns get copy-pasted, so be explicit: for any MCP server that is untrusted, write-capable, or acts on private state, use `require_approval: \"always\"` together with a tight `allowed_tools` allowlist, so every call is surfaced for human approval before it runs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"TF_MCP_TOOL = {\n",
" \"type\": \"mcp\",\n",
" \"server_label\": \"tensorfeed\",\n",
" \"server_url\": \"https://tensorfeed.ai/api/mcp\",\n",
" # allowed_tools is a least-privilege allowlist (see the security note above).\n",
" # Omit it to expose all 17 TF tools; here we grant only the three we need.\n",
" \"allowed_tools\": [\n",
" \"get_cve_record\",\n",
" \"get_kev_catalog\",\n",
" \"get_epss_score\",\n",
" ],\n",
" # Acceptable here only because the TF MCP server is read-only public data.\n",
" # Use \"always\" for untrusted or write-capable servers.\n",
" \"require_approval\": \"never\",\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Demo 1: Verify a single CVE\n",
"\n",
"CVE-2024-3094 (the XZ backdoor, March 2024) is a useful test case: it has a complete MITRE record and EPSS data; KEV presence varies by snapshot. The model should consult all three sources and report whichever subset has data.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"response = client.responses.create(\n",
" model=MODEL,\n",
" tools=[TF_MCP_TOOL],\n",
" input=(\n",
" \"Verify CVE-2024-3094 across multiple databases. Call MITRE for the canonical record, \"\n",
" \"check the CISA KEV catalog for active exploitation, and pull the FIRST.org EPSS score. \"\n",
" \"Then summarize: severity_band, exploited_in_wild boolean (true if KEV has the CVE), \"\n",
" \"epss_probability, a confirmed_by list of the databases that returned data, and a \"\n",
" \"one-sentence triage recommendation.\"\n",
" ),\n",
")\n",
"\n",
"print(response.output_text)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Demo 2: Triage three CVEs by composite risk\n",
"\n",
"A more realistic agent task: given a list of CVEs that landed in your security feed today, decide which to patch first. The model fans out across all three sources for each CVE and returns a ranked list with reasoning.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"triage = client.responses.create(\n",
" model=MODEL,\n",
" tools=[TF_MCP_TOOL],\n",
" input=\"\"\"I have three CVEs to triage. For each, look up MITRE/KEV/EPSS via tensorfeed\n",
"and rank them by patch priority. Brief reasoning per CVE plus an ordered list at the end.\n",
"\n",
"CVEs to triage:\n",
"- CVE-2024-3094\n",
"- CVE-2023-44487\n",
"- CVE-2024-21626\"\"\",\n",
")\n",
"\n",
"print(triage.output_text)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The corroboration trail\n",
"\n",
"The prose answers above are the model's summary. For a notebook whose whole premise is \"do not trust a single source,\" the summary itself should not be trusted on faith either. The Responses output also carries every MCP tool call the model actually made, as `mcp_call` items. Printing them turns \"the model says it checked three databases\" into \"here are the three databases it checked, per CVE.\" For a security pattern, this audit cell is the point, not an extra."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Pull the MCP tool calls out of the Responses output and show the audit trail.\n",
"# This is the evidence behind the confirmed_by / corroboration claim.\n",
"from collections import Counter\n",
"\n",
"calls = [item for item in triage.output if getattr(item, \"type\", None) == \"mcp_call\"]\n",
"\n",
"print(f\"{len(calls)} MCP tool calls during triage:\\n\")\n",
"for c in calls:\n",
" failed = getattr(c, \"error\", None)\n",
" status = \"error\" if failed else \"ok\"\n",
" print(f\" {c.server_label}.{c.name} [{status}]\")\n",
" print(f\" args: {c.arguments}\")\n",
"\n",
"# Each CVE should reach all three databases. The per-tool tally makes that visible.\n",
"tally = Counter(c.name for c in calls)\n",
"print(\"\\nPer-source call counts:\", dict(tally))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What just happened\n",
"\n",
"The Responses API took our MCP server URL plus a natural-language instruction and:\n",
"\n",
"1. Recognized that \"verify\" implies cross-source corroboration\n",
"2. Sequenced the calls (MITRE first to confirm the record exists, KEV for active exploitation, EPSS for likelihood)\n",
"3. Surfaced a `confirmed_by` list so the user can audit which databases backed the answer\n",
"\n",
"For the triage task it fanned out across the three CVEs and produced a ranked list. You do not have to take that on faith: the cell above prints the actual `mcp_call` trail, so every figure in the summary traces back to a specific database call you can inspect. Because the answer is composed from independent sources, a single-source error surfaces as a disagreement instead of propagating silently. That is the property you want for security, compliance, and finance agents. From the developer's perspective the whole thing is a single `responses.create` call.\n",
"\n",
"## Going further\n",
"\n",
"TensorFeed also offers a paid endpoint that performs this MITRE/KEV/EPSS composition server-side in a single call. The free three-tool pattern shown above is sufficient for most agent workloads; see [tensorfeed.ai](https://tensorfeed.ai) for details on the hosted composition. Everything in this notebook uses only the free tier.\n",
"\n",
"## Resources\n",
"\n",
"- TensorFeed.ai: https://tensorfeed.ai\n",
"- Endpoint catalog: https://tensorfeed.ai/api/meta\n",
"- Agent-friendly entry doc: https://tensorfeed.ai/llms.txt\n",
"- TF in the official MCP Registry: https://registry.modelcontextprotocol.io/ (`ai.tensorfeed/mcp-server`)\n",
"- Source code (public): https://github.com/RipperMercs/tensorfeed\n",
"\n",
"*Author note: this notebook was contributed by the maintainer of TensorFeed and uses only its free tier. The paid endpoint mentioned above is optional and is not required to run anything here.*"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.11"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
12 changes: 12 additions & 0 deletions registry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3232,3 +3232,15 @@
- agents
- memory
- compaction
- title: Cross-Database CVE Verification with TensorFeed (Hosted MCP)
path: examples/mcp/tensorfeed_cve_verification.ipynb
slug: tensorfeed-cve-verification
description: Compose three independent vulnerability databases (MITRE / CISA KEV / FIRST.org EPSS) via TensorFeed.ai's hosted MCP server using the Responses API's native MCP tool. Anti-hallucination corroboration pattern for security agents in a single Responses call.
date: 2026-05-09
authors:
- ripper
tags:
- mcp
- agents
- security