Ethiack Docs

MCP Server

Five read-only MCP tools at https://zero.ethiack.com/mcp to check installed packages against Zero entries, search new CVEs by check, exploit and KEV status, and read one entry's full record.

Endpoint: https://zero.ethiack.com/mcp, streamable HTTP.

Ask your agentCall it makes
Which of my installed packages have Zero entries, and what do I upgrade to?check_packages with {"packages": [{"name": "simple-git", "version": "3.27.0", "ecosystem": "npm"}]}
KEV-listed vulnerabilities from the last 30 days that Ethiack can detectsearch_feed with {"kev": true, "check": true, "since_days": 30}
How long before cve.org published CVE-2026-109954 did Ethiack have a check?get_entry with {"handle": "CVE-2026-109954"}, then signals.check.days
What is Zero analysing right now?live_runs
What are the median leads over cve.org, and is the feed current?feed_summary

The same call without a client:

curl -s https://zero.ethiack.com/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_entry","arguments":{"handle":"CVE-2026-109954"}}}' \
  | jq '.result.structuredContent.signals.check'
{
  "at": "2026-10-01T02:18:54.002123+00:00",
  "days": -12.46417835505787,
  "is_lower_bound": false,
  "measured_at": "2026-10-13T13:27:19.012000+00:00",
  "url": null
}

Endpoint

PropertyValue
TransportJSON responses. Stateless: no session id, and tools/call works without initialize.
AnnotationsEvery tool: readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false.
ResultsOne JSON object per call, in result.structuredContent and as text in result.content[0].text.
ErrorsInvalid arguments return isError: true with the validation message as text.
Request sizeBodies over 64 KB return HTTP 413.
Auth, licenseAccess

Connect

Claude

Customize > Connectors > + Add > Add custom connector. Enter a name and https://zero.ethiack.com/mcp, select Continue, choose No sign in under Authentication, then Add. On Team and Enterprise plans an Owner adds it under Organization settings > Connectors (Add > Custom > Web), and members connect it from Customize > Connectors.

Claude Code

claude mcp add --transport http ethiack-zero https://zero.ethiack.com/mcp

Add --scope user to make it available in every project.

ChatGPT

chatgpt.com/plugins > + > Add custom MCP server. Enter a name and description, set the connection to the public endpoint https://zero.ethiack.com/mcp with no authentication, accept the risk warning, then Create as a plugin. Account and workspace policies decide whether custom MCP servers are allowed.

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (project)
{
  "mcpServers": {
    "ethiack-zero": {
      "url": "https://zero.ethiack.com/mcp"
    }
  }
}

VS Code

.vscode/mcp.json
{
  "servers": {
    "ethiack-zero": {
      "type": "http",
      "url": "https://zero.ethiack.com/mcp"
    }
  }
}

For every workspace, add the same entry to the user mcp.json (MCP: Open User Configuration).

Tools

check_packages

Feed entries naming each installed package, with affected ranges, fixed versions and mitigation.

ParameterTypeDefaultValues and limits
packagesarray of objectsrequiredUp to 200; the rest are dropped and truncated is true. Keys name, version and ecosystem, all strings. Other keys are ignored, values are cut at 200 characters.
  • name matches an affected package (simple-git, org.jline:jline-builtins), or a product alone or with its vendor (RouterOS, Microsoft SharePoint). Exact, case-insensitive.
  • ecosystem narrows the match, and entries with no ecosystem still match. Common spellings are one ecosystem: PyPI, pip and python; npm and node; go and golang.
  • With a PyPI ecosystem, -, _ and . are equivalent in names: python_jose matches python-jose.
  • version is echoed back, not compared. Compare it with affected_ranges yourself.
  • No entries means the feed names none, not that the package is unaffected: the feed does not cover every vulnerability (methodology).

Returns checked, with_entries, truncated and results: one item per package that has entries, with the input as package and up to 10 entries, newest first, in the compact shape.

Sent simple-git (npm) and requests (PyPI); requests has no entries, so it is not in results:

result (trimmed)
{
  "checked": 2,
  "with_entries": 1,
  "truncated": false,
  "results": [
    {
      "package": { "name": "simple-git", "version": "3.27.0", "ecosystem": "npm" },
      "entries": [
        {
          "display_id": "CVE-2026-102826",
          "etk_id": "ETK-2026-698",
          "title": "Command injection through clone options in simple-git",
          "status": "published",
          "anchor_state": "anchored",
          "details_pending": false,
          "check": true,
          "check_confidence_basis": "assessed",
          "exploit": false,
          "cvss_score": 8.1,
          "affected": [
            {
              "package_name": "simple-git",
              "ecosystem": "npm",
              "purl": "pkg:npm/simple-git",
              "affected_ranges": ["<= 3.36.0"],
              "affected_notes": [],
              "fixed_versions": ["4.0.0"]
            }
          ],
          "mitigation": "Upgrade the npm simple-git package to version 4.0.0 or later. ...",
          "days_from_cve_publication": {
            "trigger_signal": { "days": 0.0, "is_lower_bound": false },
            "check": { "days": 6.247449028229167, "is_lower_bound": false }
          },
          "url": "https://zero.ethiack.com/e/CVE-2026-102826"
        }
      ]
    }
  ]
}

search_feed

The feed, newest first. Each filter is the List Entries parameter in the last column.

ParameterTypeDefaultFeed API equivalent
querystringnoneq
statusstringnonestatus. Any other value is an argument error.
checkbooleannonecheck
exploitbooleannoneexploit
kevbooleannonekev
public_pocbooleannonepoc
awaiting_cvebooleannoneanchor_state: true is awaiting_cve, false is anchored.
vendorstringnonevendor
productstringnoneproduct
since_daysintegernonesince_days. 0 or less is ignored.
limitinteger20Clamped to 1 to 50.
pageinteger1Below 1 reads as 1. Offset-based: to walk the whole feed, use cursor on List Entries.

Returns total, page, pages and entries, in the compact shape.

get_entry

ParameterTypeDefaultValues and limits
handlestringrequiredAny handle Get Entry takes. Cut at 64 characters.

Returns the body of GET /api/v1/feed/{handle}, plus url as in the compact shape. An unknown handle returns {"error": "not_found", "handle": "..."}, with isError: false.

live_runs

No parameters. Returns the body of GET /api/v1/live.

feed_summary

No parameters. Returns summary, the object of the same name in GET /api/v1/feed, and status, the GET /status body without checked_at.

result
{
  "summary": {
    "entries": 1859,
    "feed_rows": 1870,
    "anchored": 1704,
    "awaiting_cve": 155,
    "in_pipeline": 4,
    "with_check": 809,
    "with_exploit": 28,
    "deterministic": 760,
    "contextual": 1096,
    "no_prior_signal": 1567,
    "median_check_delta_days": 0.22095655906828704,
    "median_exploit_delta_days": 0.15951611630787038,
    "median_first_artifact_days": 0.22095655906828704,
    "median_sample_size": 1704,
    "median_minutes_to_start": 175.75760651666667,
    "median_minutes_to_artifact": 396.36639615,
    "watermark": "2026-10-18T01:27:28.116351+00:00"
  },
  "status": { "status": "ok", "reasons": [] }
}

Compact entry

What check_packages and search_feed return per entry. These keys carry the same values as in the entry: display_id, etk_id, cve_id, ghsa_id, euvd_id, title, status, details_pending, anchor_state, check, check_confidence_basis, exploit, cvss_score, vendor, product, affected, mitigation.

FieldMeaning
days_from_cve_publicationIn place of signals: each signal present, with only days and is_lower_bound.
urlhttps://zero.ethiack.com/e/<display_id>

On this page