<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gustavo</title>
    <description>The latest articles on DEV Community by Gustavo (@gustavo_gated).</description>
    <link>https://dev.to/gustavo_gated</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3967192%2F6cd8f3c2-5414-48d5-afb3-bd1bc7f6c20c.png</url>
      <title>DEV Community: Gustavo</title>
      <link>https://dev.to/gustavo_gated</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gustavo_gated"/>
    <language>en</language>
    <item>
      <title>The 2026-07-28 MCP Spec: A Server Readiness Checklist</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Fri, 19 Jun 2026 15:15:56 +0000</pubDate>
      <link>https://dev.to/gustavo_gated/the-2026-07-28-mcp-spec-a-server-readiness-checklist-14nf</link>
      <guid>https://dev.to/gustavo_gated/the-2026-07-28-mcp-spec-a-server-readiness-checklist-14nf</guid>
      <description>&lt;p&gt;The next Model Context Protocol specification, &lt;code&gt;2026-07-28&lt;/code&gt;, is the largest revision since the protocol launched. The release candidate locked on May 21, 2026, and the final spec publishes on July 28. It contains breaking changes to transport, authorization, and how tool schemas are handled.&lt;/p&gt;

&lt;p&gt;A server that is correct against &lt;code&gt;2025-11-25&lt;/code&gt; today is not broken. Nothing here is a present-tense vulnerability. But several of these changes are security properties, not just compatibility ones — request routing integrity, cross-user cache scope, and schema-driven fetch behavior all move under this revision. This checklist walks the changes a server operator needs to handle before July 28, and calls out the security implication wherever there is one.&lt;/p&gt;

&lt;p&gt;Everything below describes the release candidate. Treat specifics as subject to change until the July 28 final, and validate against the official spec before shipping.&lt;/p&gt;




&lt;h2&gt;
  
  
  Transport: the stateless core
&lt;/h2&gt;

&lt;p&gt;This is the headline change. MCP becomes stateless at the protocol layer, and most of the migration work lives here.&lt;/p&gt;

&lt;h3&gt;
  
  
  The handshake and session are gone
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;initialize&lt;/code&gt;/&lt;code&gt;initialized&lt;/code&gt; handshake is removed (SEP-2575). Protocol version, client info, and client capabilities no longer get exchanged once at connection time — they travel in &lt;code&gt;_meta&lt;/code&gt; on every request. The same SEP adds &lt;code&gt;server/discover&lt;/code&gt; as the new discovery anchor: servers must implement it, and clients fetch server capabilities from it when they need them up front. Once the handshake is gone, a server that can't answer &lt;code&gt;server/discover&lt;/code&gt; can't be negotiated with.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Mcp-Session-Id&lt;/code&gt; header and the protocol-level session it carried are also removed (SEP-2567). Any request can now land on any server instance. The sticky routing and shared session stores that horizontal deployments relied on are no longer required at the protocol layer.&lt;/p&gt;

&lt;p&gt;If a server needs state across calls, mint an explicit handle from a tool — a &lt;code&gt;basket_id&lt;/code&gt;, a &lt;code&gt;browser_id&lt;/code&gt; — and have the model pass it back as an ordinary argument. The state becomes a visible tool input rather than something hidden in transport metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  Required routing headers
&lt;/h3&gt;

&lt;p&gt;The Streamable HTTP transport now requires &lt;code&gt;Mcp-Method&lt;/code&gt; and &lt;code&gt;Mcp-Name&lt;/code&gt; headers (SEP-2243), so load balancers, gateways, and rate-limiters can route on the operation without reading the body. Requests also carry &lt;code&gt;MCP-Protocol-Version&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Servers must reject requests where the headers and the body disagree. This is a request-integrity check, not just a convenience: a mismatch between the routing header and the actual method in the body is exactly the kind of ambiguity that smuggling and confused-routing attacks exploit. Enforce the agreement; don't route on the header and execute the body.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accept self-contained requests that carry protocol version, client info, and capabilities in &lt;code&gt;_meta&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Implement &lt;code&gt;server/discover&lt;/code&gt; for capability negotiation&lt;/li&gt;
&lt;li&gt;Stop depending on &lt;code&gt;Mcp-Session-Id&lt;/code&gt; and stop requiring sticky sessions&lt;/li&gt;
&lt;li&gt;Require &lt;code&gt;Mcp-Method&lt;/code&gt; and &lt;code&gt;Mcp-Name&lt;/code&gt;, and reject header/body mismatches&lt;/li&gt;
&lt;li&gt;Move any cross-call state to explicit, model-visible handles&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Server-to-client requests
&lt;/h2&gt;

&lt;p&gt;A stateless protocol still needs a way for a server to ask the client for something mid-call. Two changes rebuild that flow without a persistent connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Elicitation only during active processing
&lt;/h3&gt;

&lt;p&gt;Server-initiated requests may now only be issued while the server is actively processing a client request (SEP-2260). Earlier versions recommended this; it is now required.&lt;/p&gt;

&lt;p&gt;The security value is concrete. A user is never prompted out of nowhere, and every elicitation traces back to an action they or their agent started. An unsolicited server-initiated prompt is now a spec violation, which makes a whole class of social-engineering-via-prompt behavior detectable rather than ambiguous.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi round-trip results
&lt;/h3&gt;

&lt;p&gt;Instead of holding a Server-Sent Events stream open, the server returns an &lt;code&gt;InputRequiredResult&lt;/code&gt; carrying an opaque &lt;code&gt;requestState&lt;/code&gt; (SEP-2322). The client gathers answers and re-issues the original call with &lt;code&gt;inputResponses&lt;/code&gt; and the echoed &lt;code&gt;requestState&lt;/code&gt;, and any instance can pick the retry up.&lt;/p&gt;

&lt;p&gt;Treat &lt;code&gt;requestState&lt;/code&gt; as untrusted on the way back in. It leaves the server, sits client-side, and returns. Integrity-protect it — sign or encrypt it — so a modified &lt;code&gt;requestState&lt;/code&gt; can't replay or escalate a half-finished operation. Don't deserialize it into trusted server state without verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Issue server-initiated requests only while handling a client call&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;InputRequiredResult&lt;/code&gt; rather than holding an SSE stream open&lt;/li&gt;
&lt;li&gt;Integrity-protect &lt;code&gt;requestState&lt;/code&gt; and verify it on retry&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Caching and tracing
&lt;/h2&gt;

&lt;p&gt;Three smaller changes make the resulting traffic easier to operate — and two of them carry data across boundaries that deserve attention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cache scope is a tenancy boundary
&lt;/h3&gt;

&lt;p&gt;List and resource-read results now carry &lt;code&gt;ttlMs&lt;/code&gt; and &lt;code&gt;cacheScope&lt;/code&gt;, modeled on HTTP &lt;code&gt;Cache-Control&lt;/code&gt; (SEP-2549). Clients learn exactly how long a &lt;code&gt;tools/list&lt;/code&gt; response stays fresh and whether it is safe to share across users.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cacheScope&lt;/code&gt; is where this becomes a security decision. If a server exposes a per-user or per-tenant tool surface but marks the result shareable, a client may serve one user's tool list to another. Set &lt;code&gt;cacheScope&lt;/code&gt; to match the actual sensitivity of what the response reveals, and default to the narrower scope when unsure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trace context propagation
&lt;/h3&gt;

&lt;p&gt;W3C Trace Context propagation in &lt;code&gt;_meta&lt;/code&gt; is now documented, fixing the &lt;code&gt;traceparent&lt;/code&gt;, &lt;code&gt;tracestate&lt;/code&gt;, and &lt;code&gt;baggage&lt;/code&gt; key names (SEP-414). A trace can follow a call through the client SDK, the server, and whatever the server calls downstream, and show up as one span tree in an OpenTelemetry-compatible backend.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;baggage&lt;/code&gt; is the field to watch. It propagates arbitrary key-value data downstream by design, which is useful and also a path for sensitive values to cross into systems that shouldn't see them. Decide deliberately what goes into &lt;code&gt;baggage&lt;/code&gt;, and strip or scrub it at trust boundaries rather than forwarding everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Emit accurate &lt;code&gt;ttlMs&lt;/code&gt; on list and resource-read results&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;cacheScope&lt;/code&gt; to match per-user or per-tenant sensitivity&lt;/li&gt;
&lt;li&gt;Use the fixed trace key names, and control what &lt;code&gt;baggage&lt;/code&gt; carries across boundaries&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Authorization hardening
&lt;/h2&gt;

&lt;p&gt;Six SEPs align the authorization spec more closely with how OAuth 2.0 and OpenID Connect are deployed. These matter most to operators who run their own authorization server or broker auth in front of a server.&lt;/p&gt;

&lt;p&gt;Authorization servers should supply the &lt;code&gt;iss&lt;/code&gt; parameter on authorization responses per RFC 9207 (SEP-2468). Clients are now expected to validate it, and in a future version they will reject responses that omit it. This is a low-cost mitigation for a mix-up attack that is more likely in MCP's single-client, many-server pattern — so begin supplying &lt;code&gt;iss&lt;/code&gt; now if you don't already.&lt;/p&gt;

&lt;p&gt;The remaining changes are smaller but worth handling together: support the OpenID Connect &lt;code&gt;application_type&lt;/code&gt; during Dynamic Client Registration so desktop and CLI clients aren't defaulted to &lt;code&gt;"web"&lt;/code&gt; and rejected (SEP-837); bind registered credentials to the issuing authorization server's &lt;code&gt;issuer&lt;/code&gt; and re-register when a resource migrates (SEP-2352); document how to request refresh tokens from OIDC-style servers (SEP-2207); and follow the clarified scope-accumulation and &lt;code&gt;.well-known&lt;/code&gt; discovery rules (SEP-2350, SEP-2351).&lt;/p&gt;

&lt;h3&gt;
  
  
  Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Supply &lt;code&gt;iss&lt;/code&gt; on authorization responses&lt;/li&gt;
&lt;li&gt;Honor &lt;code&gt;application_type&lt;/code&gt; in Dynamic Client Registration&lt;/li&gt;
&lt;li&gt;Bind credentials to the issuer and re-register on resource migration&lt;/li&gt;
&lt;li&gt;Follow the documented refresh-token, scope-accumulation, and discovery rules&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tool schemas
&lt;/h2&gt;

&lt;p&gt;Tool &lt;code&gt;inputSchema&lt;/code&gt; and &lt;code&gt;outputSchema&lt;/code&gt; are lifted to full JSON Schema 2020-12 (SEP-2106). Input schemas keep the &lt;code&gt;type: "object"&lt;/code&gt; root but now allow composition (&lt;code&gt;oneOf&lt;/code&gt;, &lt;code&gt;anyOf&lt;/code&gt;, &lt;code&gt;allOf&lt;/code&gt;), conditionals, and references (&lt;code&gt;$ref&lt;/code&gt;, &lt;code&gt;$defs&lt;/code&gt;). Output schemas are unrestricted, and &lt;code&gt;structuredContent&lt;/code&gt; can be any JSON value rather than only an object.&lt;/p&gt;

&lt;p&gt;Two constraints in this change are security constraints, and the spec states them as requirements. Implementations must not auto-dereference external &lt;code&gt;$ref&lt;/code&gt; URIs — a schema that points &lt;code&gt;$ref&lt;/code&gt; at an external URL is an SSRF and unbounded-fetch vector if you follow it. And implementations should bound schema depth and validation time, because a deeply nested or recursive schema is a denial-of-service input. If your server validates against client-supplied or third-party schemas, enforce both.&lt;/p&gt;

&lt;p&gt;Separately, the error code for a missing resource changes from the MCP-custom &lt;code&gt;-32002&lt;/code&gt; to the JSON-RPC standard &lt;code&gt;-32602&lt;/code&gt; Invalid Params (SEP-2164). If any code matches on the literal &lt;code&gt;-32002&lt;/code&gt;, update it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accept JSON Schema 2020-12 input and output schemas&lt;/li&gt;
&lt;li&gt;Never auto-dereference external &lt;code&gt;$ref&lt;/code&gt; URIs&lt;/li&gt;
&lt;li&gt;Bound schema depth and validation time&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;-32602&lt;/code&gt; for missing resources, and update any matching on &lt;code&gt;-32002&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Deprecations
&lt;/h2&gt;

&lt;p&gt;Roots, Sampling, and Logging are deprecated under the new feature lifecycle policy (SEP-2577). These are annotation-only deprecations: they keep working in this release and in every spec version published within a year, and removal requires a separate SEP. There is no forced cutover on July 28 — but plan the replacements now.&lt;/p&gt;

&lt;p&gt;The documented replacements are tool parameters, resource URIs, or server configuration in place of Roots; direct integration with an LLM provider API in place of Sampling; and &lt;code&gt;stderr&lt;/code&gt; (for stdio transports) or OpenTelemetry in place of Logging.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Inventory any use of Roots, Sampling, or Logging&lt;/li&gt;
&lt;li&gt;Plan migration to the documented replacements before the lifecycle clock runs out&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Extensions
&lt;/h2&gt;

&lt;p&gt;Extensions are now first-class (SEP-2133). They are identified by reverse-DNS IDs, negotiated through an &lt;code&gt;extensions&lt;/code&gt; map on client and server capabilities, and versioned independently of the specification.&lt;/p&gt;

&lt;p&gt;Two official extensions ship with this release. Tasks graduates from an experimental core feature to an extension with a redesigned, stateless lifecycle: a server answers &lt;code&gt;tools/call&lt;/code&gt; with a task handle, and the client drives it with &lt;code&gt;tasks/get&lt;/code&gt;, &lt;code&gt;tasks/update&lt;/code&gt;, and &lt;code&gt;tasks/cancel&lt;/code&gt;. &lt;code&gt;tasks/list&lt;/code&gt; is removed (SEP-2663) because it can't be scoped safely without sessions. Anyone who built against the &lt;code&gt;2025-11-25&lt;/code&gt; experimental Tasks API needs to migrate.&lt;/p&gt;

&lt;p&gt;MCP Apps (SEP-1865) lets servers ship interactive HTML interfaces that hosts render in a sandboxed iframe. Tools declare their UI templates ahead of time so hosts can prefetch, cache, and security-review them before anything runs, and every UI-initiated action goes through the same audit and consent path as a direct tool call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Negotiate extensions through the &lt;code&gt;extensions&lt;/code&gt; capability map&lt;/li&gt;
&lt;li&gt;Migrate any experimental Tasks usage to the extension lifecycle&lt;/li&gt;
&lt;li&gt;If shipping a UI, declare MCP Apps templates ahead of time for host review&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What to do now
&lt;/h2&gt;

&lt;p&gt;The ten-week window between the May 21 lock and the July 28 final exists for exactly this: validate the changes against real workloads before they become normative. Start a migration branch if you operate a remote MCP server, run your own authorization, or build against the experimental Tasks API. The transport rework is the largest piece; the auth and schema constraints are the ones with security teeth.&lt;/p&gt;

&lt;p&gt;Most of these are checkable from outside the server — the routing-header enforcement, the cache scope on list responses, the &lt;code&gt;$ref&lt;/code&gt; handling, the &lt;code&gt;iss&lt;/code&gt; parameter. Gated inspects deployed MCP servers against these and the rest of &lt;a href="https://dev.to/docs/catalog"&gt;its check library&lt;/a&gt;, mapping each to the &lt;a href="https://dev.to/docs/catalog/conformance"&gt;conformance&lt;/a&gt; and &lt;a href="https://dev.to/docs/catalog/security"&gt;security&lt;/a&gt; families with a reproduction for every finding — including private and internal servers &lt;a href="https://dev.to/security"&gt;reached from inside your network&lt;/a&gt;. If a security team wants the posture of a server in writing before July 28, that's the kind of thing it produces.&lt;/p&gt;

&lt;p&gt;— Gustavo, Gated&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>security</category>
      <category>ai</category>
      <category>http</category>
    </item>
    <item>
      <title>Auditing an MCP Server Against the OWASP MCP Top 10</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Tue, 09 Jun 2026 20:43:56 +0000</pubDate>
      <link>https://dev.to/gustavo_gated/auditing-an-mcp-server-against-the-owasp-mcp-top-10-37k4</link>
      <guid>https://dev.to/gustavo_gated/auditing-an-mcp-server-against-the-owasp-mcp-top-10-37k4</guid>
      <description>&lt;h2&gt;
  
  
  Auditing an MCP Server Against the OWASP MCP Top 10
&lt;/h2&gt;

&lt;p&gt;The OWASP MCP Top 10 is now the taxonomy people reach for when they talk about MCP risk. It is the framework a security team will bring into a procurement conversation, and the one practitioners increasingly cite by number. It is still a beta — Phase 3, under active community revision — but the categories are stable enough to design an audit around.&lt;/p&gt;

&lt;p&gt;So here is the practical question. You operate an MCP server. Someone hands you the Top 10 and asks how you stand against it. What does an audit actually check, category by category?&lt;/p&gt;

&lt;p&gt;Eight of the ten are testable against a running server. The remaining two are not really about a single server at all — they live in the build pipeline and in org-level governance. That split is most of the work, so it is how the rest of this is organized.&lt;/p&gt;

&lt;p&gt;A note on what "testable" means here. An audit from the network sees the deployed endpoint, with its real auth, its real TLS, its real manifest — not a config file on a developer's laptop. That vantage point decides which risks an audit can reach. It is the difference between reading what a server &lt;em&gt;claims&lt;/em&gt; and observing what it &lt;em&gt;does&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The eight an audit covers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP01 — Token Mismanagement and Secret Exposure.&lt;/strong&gt; This is the risk that credentials leak through the protocol surface: tokens in URLs, secrets echoed in tool output, access tokens with no sane expiry, credentials written into log notifications. Every one of those is observable. An audit sends real requests and reads what comes back — whether a token survives in a response body, whether the access-token lifetime is bounded, whether an error path quietly returns the credential it just rejected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP06 — Prompt Injection via Contextual Payloads.&lt;/strong&gt; MCP turns tool descriptions, prompt templates, and resource content into a second instruction channel pointed at the model. A description that contains an injection string, an invisible Unicode payload, or a known jailbreak phrase is a finding you can read straight off the manifest — no execution required. This is the part of the framework that maps most cleanly onto passive inspection, because the attack lives in text the server already serves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP07 — Insufficient Authentication and Authorization.&lt;/strong&gt; The largest testable surface, and the one with the least ambiguity. Does an unauthenticated caller get rejected? Do administrative tools require identity? Is PKCE enforced on the authorization code flow? Are expired, invalid, and revoked bearer tokens actually turned away, or does any non-empty token open the door? These are concrete request-response facts. A server either rejects the malformed call or it doesn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP02 — Privilege Escalation via Scope Creep.&lt;/strong&gt; Scope creep is harder to catch than missing auth, because it is about permissions that are technically granted but quietly too broad. The audit examines the OAuth contract: whether granted scopes match what was requested, whether resource indicators are enforced, whether the scopes a server advertises are the scopes it honors. That catches the server that hands back more than it was asked for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP05 — Command Injection and Execution.&lt;/strong&gt; A scanner can't see your shell. What it can see is whether the server validates the inputs that would feed one. Does it reject undeclared properties, enforce declared types, hold string and array bounds, refuse path traversal in resource URIs? Input validation is the observable proxy for injection resistance, and a server that enforces its declared schema closes the door that most injection walks through.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP10 — Context Injection and Over-Sharing.&lt;/strong&gt; When context is shared across sessions or agents, one task's data can surface in another's. The audit probes isolation between authorization contexts: whether task records leak across identities, whether task IDs are guessable on a no-auth deployment, whether an elicitation form quietly collects more than it should. These are boundaries you can test by holding two identities and checking what one can see of the other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP03 — Tool Poisoning.&lt;/strong&gt; Tool poisoning is an adversary corrupting the tools, interface definitions, or outputs a model depends on. It has three observable forms, and the audit reads all three. Schema poisoning and malicious descriptions show up in the manifest on the first read — the audit checks descriptions, parameter definitions, and namespaces the way the model will, before an agent acts on them. Rug pulls — a trusted tool that changes its description after you approved it — are caught by fingerprinting each tool on first sight and re-verifying that fingerprint on every reconnect, so drift becomes a finding rather than a surprise. Tool shadowing, where one server impersonates another's tools, surfaces when the audit compares tool and namespace claims across the set of servers an agent can reach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP08 — Lack of Audit and Telemetry.&lt;/strong&gt; The framework calls for disciplined logging of tool invocations and context changes. From the network, the audit checks the hygiene of that telemetry: that log notifications don't carry credentials, that log levels come from the standard set, that the logging surface follows the spec rather than leaking internal state. Good telemetry that quietly exfiltrates secrets is its own finding, and this is where it surfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two that live at a different layer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP04 — Software Supply Chain and Dependency Tampering.&lt;/strong&gt; This category is about signed components, dependency provenance, and catching a tampered package before it ships. It is a build-pipeline and SBOM concern by nature — the integrity question is settled at build time, in your CI and artifact signing, not at the running endpoint. A network audit flags adjacent signals like disclosed framework and runtime versions; the provenance work belongs upstream where the dependency tree actually lives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP09 — Shadow MCP Servers.&lt;/strong&gt; The risk here is the server nobody told the security team about — spun up for a demo, running default credentials, never inventoried. This is a discovery and governance problem: by definition it is about the servers an organization doesn't yet know it has. The lever that helps most is making the audit of known internal servers cheap enough to run everywhere, so bringing a server into governance stops being a chore.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to take from this
&lt;/h2&gt;

&lt;p&gt;Most of the OWASP MCP Top 10 is testable against a running server, and the testable part skews toward the risks that have produced real CVEs this year — auth gaps, token exposure, injection through tool descriptions. That is the part an audit gives you a clean, reproducible answer on.&lt;/p&gt;

&lt;p&gt;The remaining two are worth naming precisely. Supply-chain integrity is settled in your build pipeline; shadow servers are a discovery problem that sits above any one endpoint. The framework is most useful when you know which layer each of its risks belongs to, and which tool in your stack owns it.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>owasp</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>CTEM covers your whole attack surface. Except the part your AI agents use.</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Wed, 03 Jun 2026 22:46:31 +0000</pubDate>
      <link>https://dev.to/gustavo_gated/ctem-covers-your-whole-attack-surface-except-the-part-your-ai-agents-use-461i</link>
      <guid>https://dev.to/gustavo_gated/ctem-covers-your-whole-attack-surface-except-the-part-your-ai-agents-use-461i</guid>
      <description>&lt;p&gt;If you run a CTEM program, you have a map of your attack surface. Endpoints, identities, cloud configuration, exposed services — all scoped, ranked, and worked on a cadence.&lt;br&gt;
I'd put money on the MCP servers your agents call all day not being on it.&lt;br&gt;
Not because someone decided they didn't matter. Because nobody scoped them in — the tooling that draws your map doesn't know they exist. That blind spot is the whole subject of this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  A new exposure class, not a new category of risk
&lt;/h2&gt;

&lt;p&gt;MCP is how an AI agent reaches into your systems — the wiring that lets it read a ticket, query a database, or call an internal API on someone's behalf. Each server you stand up adds capability, and every capability is reachable by whatever drives the agent. Stack enough of them and you've built a second attack surface that nothing in your current toolchain was ever pointed at.&lt;/p&gt;

&lt;p&gt;The reason this fits CTEM rather than demanding a program of its own is that the failure modes are familiar. A poisoned dependency buried in a server's package tree. A credential pasted into a tool definition. A tool that executes with broader privilege than the caller ever had. None of that is exotic — it's the catalog you already know, moved to a layer your SAST pipeline doesn't parse and your CSPM doesn't enumerate. The pipeline doesn't see a hosted MCP server at all. The CSPM has no idea which tools an agent is allowed to call.&lt;/p&gt;

&lt;p&gt;It's the shadow-IT story again, one layer up the stack: capability arriving faster than anyone's ability to see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping MCP onto the five CTEM phases
&lt;/h2&gt;

&lt;p&gt;The useful thing about CTEM is that you don't need a new program to handle MCP. You need to extend the one you have. Each phase has a clear MCP equivalent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scoping. Add MCP servers to the surfaces you care about — public-facing endpoints and the private, internal servers behind your firewall, which is where most real exposure lives.&lt;/li&gt;
&lt;li&gt;Discovery. Inventory the servers, the tools each one exposes, and the data those tools can surface. You can't assess what you haven't enumerated.&lt;/li&gt;
&lt;li&gt;Prioritization. Rank findings by what an attacker could actually reach, not by raw count. A toxic flow that exfiltrates data outweighs a cosmetic schema warning.&lt;/li&gt;
&lt;li&gt;Validation. Confirm that a finding is exploitable, with a reproduction an engineer can run — the difference between a theoretical issue and one worth a sprint.&lt;/li&gt;
&lt;li&gt;Mobilization. Hand engineering remediation they can act on without a second meeting, and hand audit and compliance a record they can stand behind.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The phases that usually get skipped for MCP are discovery and validation. Discovery, because no one owns the inventory. Validation, because a list of maybes doesn't survive contact with an engineering backlog.&lt;/p&gt;

&lt;h2&gt;
  
  
  What discovery actually requires for MCP
&lt;/h2&gt;

&lt;p&gt;A list of server hostnames isn't an inventory. The exposure lives a layer down — in the tool definitions, the parameter schemas, the authorization model, and the data each tool will hand back when an agent asks for it.&lt;/p&gt;

&lt;p&gt;Industry research on exposure management is blunt about the cost of getting this wrong: most identified exposures turn out to be dead ends, and most remediation effort has historically gone to issues that never threatened a critical asset. Discovery that stops at the hostname guarantees you spend that effort in the wrong place. Reach the tool and schema level, and prioritization finally has something real to sort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Gated fits
&lt;/h2&gt;

&lt;p&gt;Gated is the audit layer for the MCP servers your agents already reach into. It scans deployed, hosted servers — not developer-machine configs — across security, quality, conformance, reliability, and cost, and returns ranked findings with reproductions for every one.&lt;br&gt;
Two things make that fit a CTEM program rather than sit beside one.&lt;br&gt;
One is that discovery and validation happen in the same pass. Gated enumerates the tools and schemas a server exposes, runs its checks against them, and produces a reproduction for each finding — so the output drops straight into prioritization and mobilization instead of stalling at "needs triage."&lt;/p&gt;

&lt;p&gt;The other is that the scanning suits a regulated environment. Private and internal servers are reached through a proxy; the checks run on Gated infrastructure, and no metadata leaves your network. For teams under LGPD, SOC 2, or similar obligations, the audit record — reproducible findings, provenance on every suppression — is itself a deliverable.&lt;br&gt;
Gated doesn't make you compliant. It closes the MCP gap in the program you already run, and gives you the evidence to show it's closed.&lt;br&gt;
&lt;a href="https://gated.cc/" rel="noopener noreferrer"&gt;Scan your first Server&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>mcp</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
