← Vytvářejte agenty na Cloudflare / agents / model-context-protocol / guides
Migrovat na MCP SDK v2
Tento návod pokrývá MCP SDK v2 ↗ upgrade v Agents SDK v0.20.0. Vysvětluje, jak servery přesunout na @modelcontextprotocol/server, dočasnou legacy dráhu použijte pouze tehdy, když si to vyžadují funkce závislé na relaci, a aktualizujte MCP klienty.
Zvolte cestu serveru
Pomocí následující tabulky zvolte migrační cestu:
| Aktuální server | Postup migrace |
|---|---|
| Server SDK v1 bez závislostí na relacích | Definici serveru přesuňte do factory SDK v2 a factory předejte do createMcpHandler. |
| Server SDK v1 se závislostmi na relacích | Přidejte trasu SDK v2. Zachovejte createLegacyMcpHandler pouze na dočasné starší dráze, dokud se tyto závislosti nenahradí. |
McpAgent bez starších stavových funkcí |
Migrovat přímo na tovární funkci (factory) SDK v2 a createMcpHandler. |
McpAgent která používá starší stavové funkce |
Navrhněte bezstavové ekvivalenty, souběžně obsluhujte bezstavovou i starší dráhu a poté starší dráhu vyprázdněte. |
Agents SDK v0.20.0 označuje tato API jako zastaralá:
- Předání serveru SDK v1 do
createMcpHandler. Přesuňte server na tovární funkci SDK v2. PoužijtecreateLegacyMcpHandlerpouze jako dočasný most pro chování závislé na relaci. Toto přetížení je naplánováno k odstranění v příští hlavní verzi. McpAgent. Je zastaralý a jeho funkce se dál nerozšiřují. Migrujte na novější řešení, jakmile to bude možné. Verze, ve které bude odstraněn, zatím nebyla oznámena.MCPClientManager.callTool(params, resultSchema, options)awithX402Client(...).callTool(confirm, params, resultSchema, options). PoužijtecallTool(params, options)nebocallTool(confirm, params, options)místo toho. Verze odstranění není oznámena.
experimental_createMcpHandler byl už zastaralý a jeho odstranění zůstává naplánováno na příští hlavní verzi. Přesuňte jeho server SDK v1 na továrnu SDK v2. Použijte createLegacyMcpHandler pouze na dočasné relační dráze během migrace.
Instalace balíčků MCP
Instalujte pouze ty generace balíčku MCP, které vaše aplikace importuje. Verzi v2 zachovejte přesně.
Pro bezstavový server:
npm i agents @modelcontextprotocol/[email protected] zodPro dočasnou legacy cestu:
npm i agents @modelcontextprotocol/[email protected] zodPro Agenta, který se připojuje k serverům MCP:
npm i agents @modelcontextprotocol/[email protected]Postupujte podle pokynů pro peer dependencies od svého správce balíčků. Aktualizujte přesné verze MCP na verzi Agents, která je podporuje.
Rozhodněte, zda je nutná dočasná stará trasa
Neponechávejte SDK v1 jen proto, že ho server v současnosti importuje. Přejděte přímo na tovární funkci SDK v2, pokud koncový bod nezávisí na některé z těchto funkcí závislých na relaci:
- Relace protokolu nebo dodaný
WorkerTransport - Úložiště transportu nebo přehrávání událostí
- Samostatné GET streamy
- Odeslané požadavky elicitation, sampling nebo roots
- Odstranění Session pomocí HTTP
DELETE
Pokud endpoint některou z těchto funkcí používá, nasaďte nejprve bezstavovou trasu. Trasu SDK v1 ponechte pouze do doby, než nahradíte závislost na relacích. Požadavky směrujte pomocí isLegacyRequest() jak je znázorněno v Společné spouštění bezstavových a starých tras.
Pro endpoint SDK v1, který nepoužívá McpAgent, použijte createLegacyMcpHandler pouze na této dočasné starší větvi. Odeberte jej poté, co klienti migrují a stávající relace doběhnou.
Přechod bezstavového serveru na SDK v2
Bezstavový createMcpHandler přijímá tovární funkci. Ta vrací McpServer nebo Server z @modelcontextprotocol/server.
-
Postupujte podle upstream Průvodce migrací na TypeScript SDK v2 ↗ pro změny registrace serveru.
-
Importujte server z
@modelcontextprotocol/server. -
Konstrukci a registraci serveru přesuňte do factory.
-
Ponechte výchozí export objektu Worker. Uvnitř něj
fetch()metodu, předejte tovární funkci docreateMcpHandlera volat vrácený callable stejně jako dříve. Použijtefetch(request, options?)metodu pouze pro nízkoúrovňovou integraci požadavků. -
Nepoužívejte jako výchozí export volatelnou hodnotu vrácenou handlerem Agents. Wrangler totiž výchozí exporty funkcí interpretuje jako
WorkerEntrypointtříd. -
Odeberte možnosti transportu a relace SDK v1.
-
Otestujte koncový bod s bezstavovými a staršími klienty.
import { McpServer } from "@modelcontextprotocol/server";
import { createMcpHandler } from "agents/mcp/server";
import { z } from "zod";
function createServer() {
const server = new McpServer({
name: "example-server",
version: "1.0.0",
});
server.registerTool(
"hello",
{
description: "Return a greeting",
inputSchema: { name: z.string().optional() },
},
async ({ name }) => ({
content: [{ type: "text", text: `Hello, ${name ?? "World"}!` }],
}),
);
return server;
}
export default {
fetch(request, env, ctx) {
return createMcpHandler(createServer)(request, env, ctx);
},
};import { McpServer } from "@modelcontextprotocol/server";
import { createMcpHandler } from "agents/mcp/server";
import { z } from "zod";
function createServer() {
const server = new McpServer({
name: "example-server",
version: "1.0.0",
});
server.registerTool(
"hello",
{
description: "Return a greeting",
inputSchema: { name: z.string().optional() },
},
async ({ name }) => ({
content: [{ type: "text", text: `Hello, ${name ?? "World"}!` }],
}),
);
return server;
}
export default {
fetch(request, env, ctx) {
return createMcpHandler(createServer)(request, env, ctx);
},
} satisfies ExportedHandler;Vstupní bod Workeru zůstává objektem. Mění se pouze volání handleru:
// SDK v1: pass a fresh constructed server.
return createMcpHandler(createServer())(request, env, ctx);
// SDK v2: pass the factory itself.
return createMcpHandler(createServer)(request, env, ctx);Nezjednodušujte to na export default createMcpHandler(createServer). Handler Agents je volatelný pro skládání uvnitř jiného handleru, Wrangler ale jakýkoli výchozí export funkce považuje za WorkerEntrypoint třídu.
Handler SDK v2 vytváří pro každý požadavek MCP samostatný server. Souběžné požadavky Workeru nikdy nesdílejí jednu připojenou instanci serveru.
Možnosti handleru pro bezstavové servery
Wrapper Agents přidává route, corsOptions, allowedHostnames, allowedOriginHostnames, a authContext. Zároveň předává podporované možnosti SDK v2 dál do nadřazeného handleru.
Mezi běžné možnosti patří:
| Možnost | Chování |
|---|---|
route |
Nastavuje přesnou cestu požadavku. Výchozí hodnota je /mcp. |
legacy |
Ve výchozím nastavení používá kompatibilitu se staršími verzemi. Nastavte "reject" pro čistě bezstavový endpoint. |
responseMode |
Vybírá automatické, JSON nebo SSE zpracování odpovědí. |
allowedHostnames |
Omezuje hlavičky Host na konkrétní názvy hostitelů. |
allowedOriginHostnames |
Omezuje Origins prohlížeče nebo přijímá "*" když je ověřuje důvěryhodný middleware. |
corsOptions |
Řídí hlavičky odpovědí CORS. Nastavte false k jejich odstranění. |
onerror |
Hlásí chyby handleru bez změny odpovědi. |
maxSubscriptions, keepAliveMs |
Nakonfigurujte subscriptions/listen doručení. |
Bezstavový handler odmítá tyto možnosti SDK v1:
transportstoragesessionIdGeneratoronsessioninitializedaonsessionclosedenableJsonResponseeventStoreallowedHostsaallowedOriginsenableDnsRebindingProtectionretryInterval
Použijte responseMode: "json" místo enableJsonResponse: true. Režim JSON zahazuje notifikace vydané před finálním výsledkem.
Validace originu na Workers
Wrapper Workers ověřuje každou přítomnou hodnotu Origin. Nesprávně formátované, neprůhledné a jiné než HTTP hodnoty Origin odmítá s 403.
Jeho výchozí allowlist zahrnuje Origins typu localhost a endpointu workers.dev hostname. Konkrétní corsOptions.origin také automaticky přidá svůj hostname. Handler aplikuje odpovídající kontroly Host na localhost a workers.dev koncové body.
U vlastní domény se zástupným CORS nakonfigurujte explicitně omezení Host i Origin:
export default {
fetch(request, env, ctx) {
return createMcpHandler(createServer, {
allowedHostnames: ["mcp.example.com"],
allowedOriginHostnames: ["app.example.com"],
corsOptions: { origin: "https://app.example.com" },
})(request, env, ctx);
},
};export default {
fetch(request, env, ctx) {
return createMcpHandler(createServer, {
allowedHostnames: ["mcp.example.com"],
allowedOriginHostnames: ["app.example.com"],
corsOptions: { origin: "https://app.example.com" },
})(request, env, ctx);
},
} satisfies ExportedHandler;Nastavte allowedOriginHostnames: "*" pouze tehdy, když důvěryhodný middleware ověří Origin před voláním handleru. Tato hodnota vypíná kontrolu Origin v handleru. MCP HTTP servery musí ověřovat Origin prohlížeče.
Hlavičky CORS požadavek neověří. Chraňte endpoint pomocí OAuth nebo jiné autentizační vrstvy.
Handler neodvozuje důvěryhodný allowlist hodnot Host z request.url. Pokud vaše nasazení přijímá libovolné hodnoty Host, ověřte je ještě před voláním handleru. U lokálních serverů mimo Cloudflare Workers postupujte podle pokynů nadřazeného SDK k ověřování Host a Origin.
Pochopte kompatibilitu se staršími klienty
Výchozí legacy: "stateless" nastavení podporuje běžné starší nástroje, zdroje a prompty. Tato cesta používá webově standardní transport SDK v2. Neimportuje WorkerTransport a nejde o kompletní transport s podporou relací.
Fallback má tato omezení:
- Každý POST obdrží nový server a transport.
- HTTP GET a DELETE vracejí
405. - Nezachovává se žádné ID relace MCP ani stav relace protokolu.
- Odeslané požadavky sampling, elicitation a roots okamžitě selžou.
- Samostatné streamy, přehrávání událostí a mazání relací nejsou k dispozici.
- Publikované experimentální úlohy nejsou přes tento fallback podporovány.
Při migraci těchto funkcí směrujte ovlivněné starší klienty na dočasnou createLegacyMcpHandler nebo McpAgent dráha.
Migrovat McpAgent server
Během migrace, McpAgent zůstává serverem SDK v1. Neměňte import serveru uvnitř staršího route na @modelcontextprotocol/server.
Migrovat přímo bez starších stavových funkcí
Pokud server nezávisí na stavu relace MCP, na RPC, na požadavcích odesílaných serverem klientovi, na samostatných streamech ani na přehrávání událostí, přesuňte jeho nástroje do SDK v2 factory a obsluhujte ho pomocí createMcpHandler.
Naplánujte bezstavové ekvivalenty pro stavové funkce
Pokud server používá starší stavové funkce, ponechte stávající McpAgent route, zatímco navrhujete a nasazujete bezstavové ekvivalenty:
| Stavová funkce na staré trase | Navrhněte pro bezstavovou cestu |
|---|---|
| Data aplikace klíčovaná podle relace MCP | Ukládejte data za explicitní hranicí aplikace, jako je Durable Object, D1, KV nebo R2. Přistupujte k nim pomocí autentizovaného identifikátoru vydaného serverem místo ID relace MCP. |
| Stav vícekrokové interakce | Vraťte integritou chráněný requestState hodnotou input_required. Svažte ho s ověřeným uživatelem, původní metodou a parametry a expirací. |
| Odeslané požadavky elicitation, sampling nebo roots | Vraťte inputRequired(...). Klient vložené požadavky splní a zopakuje původní operaci. |
| Samostatný stream změn seznamu | Publikujte změny přes subscriptions/listen. Klienti znovu otevřou odběr, pokud jeho stream skončí. |
| Přehrávání Session nebo obnovení přenosu | Zajistěte, aby byl každý bezstavový požadavek nezávisle obnovitelný. Postup obchodní logiky ukládejte do úložiště aplikace, nikoli do transportu MCP. |
Agent-to-McpAgent RPC |
Závislost na relaci protokolu nahraďte explicitní hranicí RPC nebo HTTP na úrovni aplikace a poté zpřístupněte bezstavové nástroje MCP samostatně. |
Starší route neodstraňujte hned, jakmile existuje bezstavová implementace. Obsluhujte obě dráhy, dokud klienti nepřejdou a stávající relace nedoběhnou.
Společné spouštění bezstavových a starých tras
Jedna adresa URL může směrovat bezstavové požadavky na SDK v2 a starší požadavky na stávající relační server.
import { isLegacyRequest } from "@modelcontextprotocol/server";
import { createMcpHandler } from "agents/mcp/server";
const stateless = createMcpHandler(createStatelessServer, {
route: "/mcp",
legacy: "reject",
});
const legacy = MyMcpAgent.serve("/mcp");
export default {
async fetch(request, env, ctx) {
if (await isLegacyRequest(request)) {
return legacy.fetch(request, env, ctx);
}
return stateless(request, env, ctx);
},
};import { isLegacyRequest } from "@modelcontextprotocol/server";
import { createMcpHandler } from "agents/mcp/server";
const stateless = createMcpHandler(createStatelessServer, {
route: "/mcp",
legacy: "reject",
});
const legacy = MyMcpAgent.serve("/mcp");
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
if (await isLegacyRequest(request)) {
return legacy.fetch(request, env, ctx);
}
return stateless(request, env, ctx);
},
} satisfies ExportedHandler<Env>;Zachovejte legacy: "reject" na bezstavovém handleru. Jinak jeho starší kompatibilní větev spotřebuje požadavky dřív, než je obdrží stavová trasa.
Nasaďte obě trasy ještě před přesunem klientů. Sledujte starší trasu a nechte stávající relace doběhnout. Starší trasu a její čistě protokolovou vazbu Durable Object odstraňte až poté, co na nich nezávisí žádní klienti. Konfiguraci migrace Durable Object řešte jako samostatný krok nasazení.
Aktualizace klientů MCP
Agents nyní používá @modelcontextprotocol/client interně. Stávající addMcpServer volání automaticky vyjednávají generaci protokolu.
Servery na bezstavové cestě používají server/discover. Agents se vrátí zpět k initialize pro starší servery Streamable HTTP, SSE a RPC.
Klientské API zahrnuje tyto změny:
callTool(params, options)je preferovaná signatura.callTool(params, resultSchema, options)zůstává dostupný, ale je zastaralý.- Typy klienta MCP nyní pocházejí z
@modelcontextprotocol/client. - Povinné bezstavové HTTP hlavičky zpracovává SDK.
- Změny v seznamu používají bezstavové subscriptions nebo starší oznámení, v závislosti na vyjednané trase.
Konfigurace elicitace pro bezstavové požadavky
Nástroje, prompty a zdroje na bezstavové cestě mohou vracet input_required prostřednictvím vícekolových požadavků (MRTR). SDK zavolá nakonfigurovaný handler elicitace a zopakuje původní operaci. Vaše původní callTool, getPrompt, nebo readResource promise zůstává nevyřízený.
Každé opakování obsahuje odpovědi pro bezprostředně předchozí vstupní kolo, nikoli všechny dřívější odpovědi. Klient také vrací poslední neprůhledný requestState. Důvěryhodné mezivýsledky potřebné pro pozdější kola zapečeťte do integritně chráněného requestState; neočekávejte inputResponses se hromadily napříč koly.
Viz příklad bezstavového vyžádání ↗ pro dvoukolový tok nástrojů.
export class MyAgent extends Agent {
onStart() {
this.mcp.configureElicitationHandlers({
form: async (request, serverId, signal) => {
return collectInput(request, serverId, signal);
},
url: async (request, serverId, signal) => {
return openExternalFlow(request, serverId, signal);
},
});
}
}export class MyAgent extends Agent<Env> {
onStart() {
this.mcp.configureElicitationHandlers({
form: async (request, serverId, signal) => {
return collectInput(request, serverId, signal);
},
url: async (request, serverId, signal) => {
return openExternalFlow(request, serverId, signal);
},
});
}
}Handlery a probíhající volání zůstávají v paměti. Hibernace, restart izolátu, ztráta přenosu nebo rekonstrukce spojení odmítne aktivní interaktivní volání. Operaci po obnovení spojení zopakujte.
Považujte ručně zpracované requestState jako nedůvěryhodný vstup. Svažte ho s ověřeným uživatelem a operací, chraňte jeho integritu a nastavte krátkou platnost.
Aktualizace vlastních poskytovatelů OAuth
Vlastní AgentMcpOAuthProvider musí implementovat v2 OAuthClientProvider kontrakt:
- Importujte typy OAuth z
@modelcontextprotocol/client. - Uložte
StoredOAuthClientInformationaStoredOAuthTokens. - Zachovejte razítko vydavatele SDK v přihlašovacích údajích.
- Uložit
OAuthDiscoveryStatenapříč přesměrováními v prohlížeči. - Přijmout
"discovery"vinvalidateCredentials. - Pokud se vydavatelé autorizace liší, uchovávejte přihlašovací údaje odděleně.
SDK v2 ve výchozím nastavení ověřuje vydavatele metadat OAuth. Důvěryhodný starší server se známými neshodujícími se metadaty může použít skipIssuerMetadataValidation: true. Tím se oslabuje ochrana proti OAuth mix-up útokům, a proto by to nemělo sloužit jako obecné záložní řešení.
Přehled rozdílů protokolů
Bezstavový model MCP mění transport a životní cyklus:
| Oblast | Předchozí chování | Nové chování |
|---|---|---|
| Spuštění | initialize handshake |
Žádný handshake. server/discover je pro klienty volitelný |
| Metadata požadavku | Vyjednávání v rámci připojení | Verze, možnosti klienta a metadata identity při každém požadavku |
| Relace | Volitelné Mcp-Session-Id |
Žádná relace protokolu |
| Požadavky na vstup serveru | Server odesílá požadavky JSON-RPC | Server vrací input_required. Klient zopakuje původní operaci |
| Oznámení o změnách | Samostatný GET stream a oznámení o změnách seznamu | subscriptions/listen POST s odpovědí SSE |
| Obnovení streamu | Last-Event-ID dokáže obnovit nakonfigurované streamy |
Naslouchací streamy se po selhání znovu otevřou. Neexistuje žádné Last-Event-ID přehrání. |
Vlastní transporty, proxy servery a brány musí zachovat hlavičky návrhu požadavku:
MCP-Protocol-VersionMcp-MethodMcp-Namepro operace s nástroji, prompty a zdroji- Deklarováno
Mcp-Param-*hlavičky nástroje
Přesná verze SDK, kterou Agents používají, implementuje revizi MCP 2026-07-28. Umožňuje clientInfo volitelný a umísťuje identitu serveru do výsledku _meta. Používejte vysokoúrovňová API SDK a aktualizujte balíčky MCP na verzi Agents, která podporuje danou revizi protokolu. Syrové bezstavové výsledky musí obsahovat resultType.
Návrh protokolu označuje Roots, Sampling, Logging, starší transport HTTP+SSE a Dynamic Client Registration jako zastaralé. Tyto typy zůstávají k dispozici po dobu období vyřazování kvůli kompatibilitě se staršími verzemi. Zveřejněné experimentální metody úloh se stávají io.modelcontextprotocol/tasks rozšíření. Agents SDK v0.20.0 toto rozšíření nepřidává.
Kompatibilita integrace
Následující integrace si v této verzi zachovávají výstup serveru SDK v1:
- Aktuální Code Mode
codeMcpServeraopenApiMcpServerpomocné funkce - Serverová strana
withX402pomocná funkce - Stávající příklady OpenAI Apps, které importují SDK v1
McpServer
Dokud tyto integrace nebudou produkovat servery SDK v2, izolujte jejich výstup za dočasným createLegacyMcpHandler route. Konektor Code Mode MCP a withX402Client přijímají obě generace klienta.
Naplánujte nasazení
-
Klasifikujte každý koncový bod podle jeho závislostí na relaci.
-
Připněte verze MCP SDK vyžadované vydáním Agents.
-
Každou definici serveru, která může být bezstavová, přesuňte do factory SDK v2.
-
Přidejte bezstavové handlery vedle endpointů, které stále potřebují dočasnou starší dráhu.
-
Směrujte bezstavové a starší požadavky pomocí
isLegacyRequest(). -
Otestujte bezstavové a starší klienty nezávisle na sobě.
-
Otestujte požadované HTTP hlavičky přes každý proxy server a bránu.
-
Otestujte OAuth po čistém přihlášení a po hibernaci Durable Object.
-
Otestujte zrušení, více kol vstupu a ztrátu transportu.
-
Ověřujte platné Origins a neplatné odmítejte s
403. -
Starší trasy odeberte až po vyprázdnění stávajících relací.
Uložená ID relací HTTP z verzí Agents starších než v0.20.0 neobsahují vyjednanou verzi protokolu. Aktualizovaný klient tato ID zahodí a znovu se připojí, místo aby odeslal nebezpečný obnovený požadavek. Probíhající práce vázaná na starou vzdálenou relaci se neobnoví.
Podrobnosti o API najdete v createMcpHandler a McpClient.