Product·16 min read

What Is an MCP Server? How MCP Works, Where It Runs and How to Secure It

A guide to the Model Context Protocol: hosts, clients and servers, the stdio and Streamable HTTP transports, OAuth 2.1 with RFC 9728, and MCP security risks with a checklist. Then the EchelonGraph MCP server: free, keyless, read-only CVE and exposure tools with verifiable SLSA provenance.

E

Akshay Dubey

Founder

The Model Context Protocol (MCP) is a standard way for AI assistants such as Claude and Cursor to reach tools and data outside the model: your files, your tickets, a database, or a live vulnerability feed. This guide explains what an MCP server is, how the protocol works, where servers run, and what can go wrong when they face the internet. It then shows what the EchelonGraph MCP server does, how to install it, and how to check what we say about it yourself.

In short:

  • An MCP server is a small program that offers an AI application a set of tools (functions the model may call), resources (data it can read) and prompts, over JSON-RPC 2.0.
  • It runs either locally over stdio (the AI app starts it as a child process; nothing listens on the network) or, typically remotely, over Streamable HTTP (a web endpoint).
  • For servers reached over HTTP the spec defines OAuth 2.1 authorization with RFC 9728 protected-resource metadata, but authorization is optional. Whether a reachable server demands credentials has to be checked, not assumed.
  • The EchelonGraph MCP server (echelongraph-mcp on npm) gives any MCP client that can run a local (stdio) server our fused CVE intelligence, plus an internet-exposure footprint for the CVEs our KEV-exposure radar tracks. It is free, keyless and read-only, answers both protocol eras, labels every result so a model cannot mistake an outage for an all-clear, and every release since 2.3.3 carries verifiable SLSA provenance.
  • What is the Model Context Protocol?

    Large language models know only what was in their training data. Ask one whether a CVE published this morning is being exploited and it will guess, or answer confidently from a snapshot that is months old. MCP fixes that plumbing problem. It is an open protocol, released by Anthropic in November 2024, that standardises how an AI application discovers and calls external capabilities, so one integration works in every compatible client instead of being rebuilt for each.

    Think of it as a common socket. Before MCP, every AI product needed custom glue for every data source. With MCP, a data source ships one server, and any host that speaks the protocol can use it: Claude Desktop, Cursor, Cline, Windsurf and others.

    How MCP works: hosts, clients and servers

    MCP architecture: a host application runs one MCP client per server; each client speaks JSON-RPC 2.0 to one MCP server, which exposes tools, resources and prompts

    There are three roles:

  • Host: the application the person uses, such as Claude Desktop or an IDE. It owns the conversation and the model, and decides which servers to connect.
  • Client: a connector inside the host. Each client holds exactly one connection to one server.
  • Server: the program that offers capabilities. It declares what it can do, and the host decides what to show the model.
  • Every message is JSON-RPC 2.0: a request with a method name and parameters, and a response or an error. Up to revision 2025-11-25, a connection starts with an initialize handshake in which the two sides agree a protocol version and state their capabilities. The 2026-07-28 revision removes that handshake: every request carries its protocol version and capabilities in _meta, and servers must also answer server/discover, which a client may call first to learn what the server supports. Either way, the client can then list the server's tools and call them.

    A server exposes three kinds of things:

  • Tools: functions the model can decide to call, each with a name, a description and a JSON Schema for its input (and, since the 2025-06-18 revision, optionally for its output). get_cve with an argument cve_id is a tool.
  • Resources: data addressed by URI that the client can read into context.
  • Prompts: reusable templates a user can pick from a menu.
  • The model never talks to your systems directly. It asks the host to call a tool, the host (usually after your approval) sends tools/call to the server, and the server's answer goes back into the conversation. That is also why the quality of a server's answers matters so much: the model treats them as ground truth.

    Where MCP servers run: stdio and Streamable HTTP

    The two MCP transports: stdio runs the server as a local child process with nothing listening on the network; Streamable HTTP is a web endpoint that should require authorization

    MCP defines two standard transports:

  • stdio (local). The host starts the server as a child process and exchanges messages over its standard input and output. Nothing listens on the network, and the server runs with your user account's permissions. Credentials, when needed, come from the environment. A common way to install one is a single entry in the client's config that runs npx -y <package> or uvx <package>.
  • Streamable HTTP (typically remote). The server is a web endpoint, often https://host/mcp. The client sends JSON-RPC in HTTP POST requests, and the server answers with JSON or streams its reply as server-sent events (SSE) on the same endpoint. Anyone who can reach the endpoint can talk to it (the spec says a server running locally should bind only to localhost). The older HTTP+SSE transport, which used a separate SSE endpoint, is deprecated in favour of Streamable HTTP.
  • The choice decides where the risk lives. For a local server, what matters is what the package does on your machine, which makes its supply chain (who built and published it) the question. For a reachable server, what matters is who can reach it and what they can do without credentials.

    MCP authorization: OAuth 2.1 and RFC 9728

    The MCP authorization flow: the client calls the server without a token, gets a 401 and discovers the RFC 9728 protected-resource metadata, finds the authorization server, obtains a token with OAuth 2.1 and PKCE, and retries with a bearer token

    For servers reached over HTTP, the MCP specification builds authorization on OAuth 2.1. The server acts as an OAuth resource server:

  • The client calls the MCP endpoint without a token.
  • A server that requires authorization answers HTTP 401, and points to its protected-resource metadata, defined by RFC 9728, either in the WWW-Authenticate header's resource_metadata parameter or at a well-known URI.
  • That metadata names the resource and at least one authorization server.
  • The client obtains an access token from one of them with the authorization-code flow and PKCE, bound to this resource.
  • Every later request carries Authorization: Bearer ….
  • Two details make this more than a formality. First, authorization is optional in MCP. A server that answers without asking for credentials may serve anyone who can reach it, but it may also enforce credentials only when a tool is called, so an answer to the first request alone does not show a server is open. Second, a 401 on its own proves little. It is the published metadata, naming this exact endpoint and an authorization server, that shows the server was built to require credentials.

    MCP security risks, and how to reduce them

    MCP gives a model hands. The risks follow from that, and most have well-understood mitigations:

  • Servers that answer without credentials. A Streamable HTTP server deployed for a demo and left reachable, with no authorization, exposes whatever its tools do. Mitigation: require OAuth 2.1 with RFC 9728 metadata, and check reachable servers rather than trusting a README.
  • Prompt injection through tool descriptions and results. Text in a tool's description or in its output can carry instructions aimed at the model ("tool poisoning"). Mitigation: install servers from publishers you can verify, review tool descriptions, keep human approval on for tool calls, and prefer servers whose outputs are structured and labelled.
  • Over-broad permissions. A local server runs as you. A file-system server pointed at your home directory can read your SSH keys. Mitigation: least privilege, a narrow scope, and a separate account or container for anything powerful.
  • Token passthrough and confused deputies. A server must not accept tokens that were not issued for it, or forward a client's token to another service; the specification forbids token passthrough. A proxy server that uses one static client ID with a third-party authorization server can be tricked into granting access without the user's consent. Mitigation: audience-bound tokens (RFC 8707 resource indicators with RFC 9728), and per-client user consent in proxy servers, as the specification's security guidance requires.
  • Supply-chain compromise. A typo-squatted or hijacked package runs with your permissions the moment the client starts it. Mitigation: pin versions, and verify provenance: that the package was built from the repository and tag it claims, by the workflow it claims.
  • A short checklist before you add any MCP server:

  • Who publishes it, and can you verify the build (provenance attestations, a public source repository, a tag per release)?
  • Is it read-only, or can it change things? Do its tool annotations say so?
  • Local or reachable over the network? If reachable, does it require authorization, with RFC 9728 metadata you can read?
  • What does it send, and where? Does it contact anything besides the API it wraps?
  • When a lookup fails, does it say so, or return an empty result the model will read as "nothing found"?
  • The last question is easy to overlook, and for security data it matters most: a model reads an empty result as "nothing found".

    The EchelonGraph MCP server

    EchelonGraph MCP data flow: NVD, MITRE CNA records, CISA KEV, FIRST EPSS and GitHub advisories fused into CVE Pulse; the KEV-exposure radar, derived from Shodan data (owned by Shodan, © Shodan), adds exposure counts; the keyless public API serves both to echelongraph-mcp running locally over stdio

    echelongraph-mcp is our MCP server for vulnerability and internet-exposure intelligence. It connects any MCP client that can run a local (stdio) server to EchelonGraph's CVE Pulse, which fuses NVD, MITRE CNA records (including records NVD has not yet enriched), the CISA Known Exploited Vulnerabilities catalogue, FIRST EPSS and GitHub security advisories into one record per CVE, with the EchelonGraph score. It adds an internet-exposure footprint for the CVEs our KEV-exposure radar tracks (CISA KEV and high-EPSS CVEs in tracked products): how many internet-facing services (distinct ip:port) the radar has on record running a version that maps to the CVE. That count is inferred from banner versions in a sample of Shodan results, not an internet-wide census, and the data is derived from Shodan data (owned by Shodan, © Shodan).

    It is free and keyless: no API key, no account, no auth, and it is read-only. It runs on your machine over stdio and makes no request other than the API call a tool needs to answer. The code is MIT-licensed, and the source is public at github.com/echelongraph/echelongraph-mcp.

    The five tools

    ToolWhat it answers
    cve_summaryCounts of active CVEs by severity band; the CVEs with no severity band from any source (not yet scored, never a rating of "None"); the same CVEs counted by NVD's severity label, as provenance; the rejected (withdrawn) records outside the total; and when the feed was last updated.
    search_cvesSearch and filter CVEs by severity, minimum CVSS, text and sort order (including by EPSS), with EchelonGraph scores, and says which rows are not yet scored.
    get_cveThe full record for one CVE: CVSS v3 and, when scored, v4; the EchelonGraph score and its confidence; EPSS; CISA KEV status and known ransomware use; the GitHub advisory id; references; and when it was published, modified and last updated.
    cve_exposureThe internet-exposure footprint for one CVE the KEV-exposure radar tracks: the count of exposed services (distinct ip:port), with a country and product breakdown, derived from Shodan data (owned by Shodan, © Shodan).
    exposure_radarAggregate totals across EchelonGraph's exposure radars (several derived from Shodan data, owned by Shodan, © Shodan): services running CISA KEV CVEs, unauthenticated data stores, leaked credentials, shadow AI, and MCP servers found in our own Certificate Transparency feed, each number labelled by what it counts.

    Ask it things like:

  • "Is CVE-2023-44487 actively exploited, and how many exposed services does EchelonGraph's radar have on record for it?"
  • "Which critical CVEs have the highest EPSS right now, and which of them are in CISA KEV?"
  • "What does EchelonGraph score CVE-2024-3400, and why is its confidence what it is?"
  • Install in Claude Desktop, Cursor, Cline or Windsurf

    You need Node.js 20 or later; npx fetches the package on first run. Add this entry to the client's MCP configuration (claude_desktop_config.json for Claude Desktop, ~/.cursor/mcp.json for Cursor, or the client's MCP settings), then restart the client:

    {
      "mcpServers": {
        "echelongraph": {
          "command": "npx",
          "args": ["-y", "echelongraph-mcp"]
        }
      }
    }

    Two optional environment variables: ECHELONGRAPH_API_BASE (default https://app.echelongraph.io) points it at another API base, and ECHELONGRAPH_API_TIMEOUT_MS (default 15000) sets the per-request timeout. A slower answer is reported as a failed lookup, not as empty data.

    Every result says what it is

    A security answer that turns an outage into "no findings" is worse than no answer. So every result from echelongraph-mcp comes in one of two shapes:

  • Success: the API's JSON (verbatim, except that exposure_radar relays only the fields it can label and names what it left out), then a one-line note saying the call succeeded, which base URL answered and what it found. When the CVE feed genuinely holds nothing for a query, the note says so in words, because a measured zero is a measurement.
  • Failure: an MCP error result (isError: true) whenever the lookup did not complete. The host was unreachable, answered non-2xx, timed out, or answered with something that is not a JSON object. The text names the tool, the cause, the path and the base URL, and a failure is never rendered as a success with empty fields.
  • Every result also carries structured content with a state of measured, not_assessed, failed or invalid_input, plus when the underlying observation was made (measured_at), how the numbers were produced (method), what the answer covers (coverage), and how fresh the producing radar is (freshness). Every tool declares its output schema and the annotations readOnlyHint: true and destructiveHint: false. Exposure answers never claim to be dated measurements they are not: a count is relayed with a label saying exactly what it counts and why it is not presented as measured.

    Counts that are easy to misread are labelled in the answer itself. For example, cve_summary tells the model that CVEs with no severity band are not yet scored, not rated "None". It also says the NVD-label histogram (NVD's label, with a pre-NVD label standing in until NVD's record arrives) is provenance, not EchelonGraph's rating, and that rejected records are withdrawn records, never vulnerabilities.

    Both protocol eras

    The server answers both eras of MCP over stdio:

  • 2026-07-28: a client that calls server/discover gets a DiscoverResult, and sends each request with the per-request _meta envelope.
  • 2025-11-25 and earlier: a client that opens with initialize negotiates 2025-11-25, 2025-06-18, 2025-03-26 or 2024-11-05.
  • Its behavioural test suite runs once as a 2026-07-28 client and once as a 2025 initialize client, with no network.

    Verify it yourself: provenance you can check

    Since version 2.3.3, every release is published by GitHub Actions from a tag in the public repository, through npm trusted publishing, with SLSA v1 provenance. After every publish, the release workflow checks that the attestation npm serves names the release workflow, the tag and the commit it was built from, and that npm audit signatures verifies it; the run fails if either check does. You do not have to take our word for it:

    npm view echelongraph-mcp dist.attestations

    npm audit signatures

    The first shows that npm holds SLSA v1 provenance for the latest version, and where to read it; the package's page on npmjs.com shows the source commit, build file and workflow run it names. The second, run with npm 9.5 or later in a project that has installed the package, verifies the registry signatures and provenance attestations of what you installed.

    Why EchelonGraph MCP

    Here is what to look for in a security MCP server, what echelongraph-mcp does for each point, and how to check it yourself:

    What to look for in a security MCP serverechelongraph-mcpHow to check
    More than one source per CVENVD, MITRE CNA records (including pre-NVD), CISA KEV, FIRST EPSS and GitHub GHSA, fused into one record with the EchelonGraph scoreget_cve on a CVE in CISA KEV, e.g. CVE-2024-3400
    Whether a CVE is exposed on the internet, not just whether it existsFor the CVEs the KEV-exposure radar tracks (CISA KEV and high-EPSS), a count of exposed services (distinct ip:port) from a sample of Shodan results, not an internet-wide census; derived from Shodan data (owned by Shodan, © Shodan)cve_exposure
    An outage never reads as an all-clearFailures are MCP errors naming the cause; a measured empty result says it looked and found nothingPoint ECHELONGRAPH_API_BASE at an unreachable host and call any tool
    Numbers that say what they countstate, measured_at, method, coverage and freshness on every result, with a declared output schematools/list, then any tool call
    Supply chain you can verifySLSA v1 provenance on every release since 2.3.3, built from a public tagnpm view echelongraph-mcp dist.attestations
    Current protocol supportBoth 2026-07-28 (server/discover) and the 2025 initialize eraRun npm test in the public repository
    Cost and frictionFree, keyless, read-only; one entry in the client's configThe config block above

    And something a CVE lookup alone cannot give you: we also measure MCP servers on the internet.

    We also measure MCP servers on the internet

    How EchelonGraph adjudicates an MCP server: opt-out register first, then server/discover; a 401 or 403 goes to RFC 9728 adjudication; the older initialize handshake only after another 4xx; protected only with matching RFC 9728 metadata; everything else not assessed

    EchelonGraph's AI-Exposure Radar looks for hostnames named like MCP servers (a label such as mcp or mcp-server) in our own Certificate Transparency feeds, which record newly issued, publicly trusted TLS certificates. It then checks, with the protocol's own requests, whether each server requires authorization. MCP servers are identified by server/discover, the older initialize handshake only when that is refused, and, on a host named like an MCP server where neither finds an MCP endpoint, the first event of the deprecated SSE transport's stream. Under the 2026-07-28 revision server/discover opens no session, and a server that answers it with a DiscoverResult, or with an error that revision defines, is sent no further POST, so it is not written to. One counts as requiring authorization only when it refuses either request with HTTP 401 or 403 and publishes matching OAuth protected-resource metadata (RFC 9728); anything short of that is reported as not assessed, never as open.

    Before any request is sent, the scan opt-out register is asked about the host, and nothing is sent if the host has opted out of Radar scanning or the register cannot be read. Every request carries our User-Agent and a signed receipt the host's owner can verify. The adjudicated counts are published on the Shadow AI radar, with their method, and exposure_radar relays the same counts to any MCP client. Our bot page documents exactly what we send and how to opt out.

    Everything else EchelonGraph does

    The MCP server is one door into a larger platform. The features page lists every capability; here is the map:

  • Free and public tools. The Surface Scanner grades a domain's external attack surface with nothing to install; CVE Pulse is the public CVE corpus; a free CVE API with no key; the MCP server; Am I affected?, a version matcher that returns the CVEs that genuinely apply to a product and version; and a compliance framework explorer.
  • Vulnerability intelligence. Pre-NVD ingestion, the EchelonGraph score, multi-source reconciliation, exploitation signals, vendor advisory aggregation, a vendor security scorecard, continuous re-scoring and lifecycle hygiene.
  • Cloud posture: CSPM, CIEM, AI-SPM and IaC. A multi-cloud posture engine (live for AWS and GCP; Azure not yet enabled), privilege-escalation paths, AI and ML service posture, cloud secrets detection, near-real-time change detection, infrastructure-as-code scanning, configuration drift and CIS benchmark mapping.
  • Attack graph and blast radius. Attack-path analysis, blast radius, CVE-to-asset matching, cross-cloud lateral movement and evidence provenance.
  • Supply chain, containers and SBOM. SBOM generation, container registry scanning and a coverage ledger.
  • Runtime and network sensors. An eBPF runtime sensor, encrypted traffic analysis, shadow API discovery, behavioural anomaly detection and Kubernetes posture.
  • Internet exposure radars. Shadow AI discovery, exposed data stores, exposed AI keys, email spoofability, subdomain takeover, our Certificate Transparency feed, and MCP server authorization adjudication.
  • Findings operations and integrations. A security copilot, remediation guidance, the findings lifecycle, alerting, SIEM and webhook export, dashboards and scheduled reports.
  • Compliance, governance and enterprise controls. Continuous compliance scoring, custom frameworks, AI governance mapping, SAML single sign-on, role-based access control and data residency (US-hosted today; EU and Asia-Pacific residency planned, not yet available).
  • Get started

  • Add echelongraph-mcp to your MCP client with the config above, and ask it about a CVE you care about.
  • Browse the same data on CVE Pulse, and see the MCP server's page at /pulse/mcp.
  • Scan your own domain with the free Surface Scanner.
  • See every capability on the features page.
  • The protocol will keep changing; 2026-07-28 is the latest revision the server supports. We update the server as MCP evolves, and every release since 2.3.3 is published from a public tag with provenance you can check.

    Protect your infrastructure before the breach

    Map your attack surface, automate compliance, and detect insider threats in real time.

    Book a demo →