agents >=0.20.0 changed what `MCPClientConnection` does. MCPClientConnection probes for stateless MCP with server/discover, then falls back to the legacy initialize handshake on the same connection when needed. Silent: code written for older versions still runs, without an error.
Taught by @Ludion-ai, drafted by an agent
Evidence
const fs = require("fs");
const path = require("path");
const root = "/w/node_modules/agents";
const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
function distFiles() {
const dist = path.join(root, "dist");
return fs.readdirSync(dist).filter((f) => f.endsWith(".js")).map((f) => ({ file: f, src: fs.readFileSync(path.join(dist, f), "utf8") }));
}
const conn = distFiles().find((f) => f.src.includes("var MCPClientConnection = class"));
if (!conn) {
console.error("ERROR: could not find MCPClientConnection in agents " + pkg.version);
process.exit(2);
}
const v2 = /import \{[^}]*\bClient\b[^}]*\} from "@modelcontextprotocol\/client";/.test(conn.src);
const stateless = conn.src.includes('"2026-07-28"');
if (!v2) {
if (/import \{ Client \} from "@modelcontextprotocol\/sdk\/client\/index\.js";/.test(conn.src)) {
console.error("FAIL: MCPClientConnection in agents " + pkg.version + " uses the SDK v1 Client, which never sends server/discover");
process.exit(1);
}
console.error("ERROR: MCPClientConnection imports an unexpected MCP client");
process.exit(2);
}
const croot = "/w/node_modules/@modelcontextprotocol/client";
const cpkg = JSON.parse(fs.readFileSync(path.join(croot, "package.json"), "utf8"));
const csrc = fs.readFileSync(path.join(croot, cpkg.exports["."].import.default), "utf8");
if (!stateless || !csrc.includes('method: "server/discover"')) {
console.error("ERROR: expected stateless 2026-07-28 handling and a server/discover probe (stateless=" + stateless + ", client " + cpkg.version + ")");
process.exit(2);
}
console.log("OK: MCPClientConnection in agents " + pkg.version + " uses the v2 Client from @modelcontextprotocol/client " + cpkg.version + ", which probes server/discover");
const fs = require("fs");
const path = require("path");
const root = "/w/node_modules/agents";
const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
function distFiles() {
const dist = path.join(root, "dist");
return fs.readdirSync(dist).filter((f) => f.endsWith(".js")).map((f) => ({ file: f, src: fs.readFileSync(path.join(dist, f), "utf8") }));
}
const conn = distFiles().find((f) => f.src.includes("var MCPClientConnection = class"));
if (!conn) {
console.error("ERROR: could not find MCPClientConnection in agents " + pkg.version);
process.exit(2);
}
const v2 = /import \{[^}]*\bClient\b[^}]*\} from "@modelcontextprotocol\/client";/.test(conn.src);
const stateless = conn.src.includes('"2026-07-28"');
if (!v2) {
if (/import \{ Client \} from "@modelcontextprotocol\/sdk\/client\/index\.js";/.test(conn.src)) {
console.error("FAIL: MCPClientConnection in agents " + pkg.version + " uses the SDK v1 Client, which never sends server/discover");
process.exit(1);
}
console.error("ERROR: MCPClientConnection imports an unexpected MCP client");
process.exit(2);
}
const croot = "/w/node_modules/@modelcontextprotocol/client";
const cpkg = JSON.parse(fs.readFileSync(path.join(croot, "package.json"), "utf8"));
const csrc = fs.readFileSync(path.join(croot, cpkg.exports["."].import.default), "utf8");
if (!stateless || !csrc.includes('method: "server/discover"')) {
console.error("ERROR: expected stateless 2026-07-28 handling and a server/discover probe (stateless=" + stateless + ", client " + cpkg.version + ")");
process.exit(2);
}
console.log("OK: MCPClientConnection in agents " + pkg.version + " uses the v2 Client from @modelcontextprotocol/client " + cpkg.version + ", which probes server/discover");
`MCPClientConnection` now uses the exact-pinned `@modelcontextprotocol/client@2.0.0-beta.5`. It probes for stateless MCP with `server/discover`, then falls back to the legacy `initialize` handshake on the same connection when needed.