INTEGRITY Dokumentace

Nástroje

Nástroje MCP jsou funkce, které server MCP zpřístupňuje, aby je mohli volat klienti. LLM může nástroj vyvolat, aby vyhledal data, provedl výpočet nebo zavolal API. MCP server nástroj spustí a vrátí jeho výsledek.

Použijte @modelcontextprotocol/server pro bezstavový createMcpHandler server. McpAgent je zastaralé a jeho funkce se dále nerozvíjejí. Stávající McpAgent routy musí i nadále používat @modelcontextprotocol/sdk pouze během migrace.

Příklad WebMCP

Přemostěte nástroje MCP z Cloudflare McpAgent do experimentálního WebMCP API prohlížeče Chrome.

Definování nástrojů

Použijte server.registerTool() k registraci nástroje u bezstavového McpServer instance. Každý nástroj má název, popis a vstupní schéma definované pomocí knihovny schémat, jako je Zod ↗ nebo Valibot ↗, a funkci handleru.

import { McpServer } from "@modelcontextprotocol/server";
import { z } from "zod";

function createServer() {
	const server = new McpServer({ name: "Math", version: "1.0.0" });

	server.registerTool(
		"add",
		{
			description: "Add two numbers together",
			inputSchema: { a: z.number(), b: z.number() },
		},
		async ({ a, b }) => ({
			content: [{ type: "text", text: String(a + b) }],
		}),
	);

	return server;
}
import { McpServer } from "@modelcontextprotocol/server";
import { z } from "zod";

function createServer() {
	const server = new McpServer({ name: "Math", version: "1.0.0" });

	server.registerTool(
		"add",
		{
			description: "Add two numbers together",
			inputSchema: { a: z.number(), b: z.number() },
		},
		async ({ a, b }) => ({
			content: [{ type: "text", text: String(a + b) }],
		}),
	);

	return server;
}

Handler nástroje přijímá ověřený vstup a musí vrátit objekt s content pole. Každá položka obsahu má type (obvykle "text") a odpovídající data.

Výsledky nástrojů

Výsledky nástrojů se vrací jako pole částí obsahu. Nejběžnějším typem je text, ale můžete vracet i obrázky a vložené prostředky.

server.registerTool(
	"lookup",
	{
		description: "Look up a user by ID",
		inputSchema: { userId: z.string() },
	},
	async ({ userId }) => {
		const user = await db.getUser(userId);

		if (!user) {
			return {
				isError: true,
				content: [{ type: "text", text: `User ${userId} not found` }],
			};
		}

		return {
			content: [{ type: "text", text: JSON.stringify(user, null, 2) }],
		};
	},
);
server.registerTool(
	"lookup",
	{
		description: "Look up a user by ID",
		inputSchema: { userId: z.string() },
	},
	async ({ userId }) => {
		const user = await db.getUser(userId);

		if (!user) {
			return {
				isError: true,
				content: [{ type: "text", text: `User ${userId} not found` }],
			};
		}

		return {
			content: [{ type: "text", text: JSON.stringify(user, null, 2) }],
		};
	},
);

Nastavte isError: true k signalizaci, že volání nástroje selhalo. LLM obdrží chybovou zprávu a může se rozhodnout, jak dále postupovat.

Popisy nástrojů

description parametr je klíčový: podle něj LLM rozhoduje, zda a kdy váš nástroj zavolat. Pište popisy, které jsou:

Validace vstupu pomocí Zod

Vstupy nástrojů se definují jako schémata Zod a před spuštěním handleru se automaticky validují. Použijte .describe() metodu, která LLM poskytne kontext o každém parametru.

server.registerTool(
	"search",
	{
		description: "Search for documents by query",
		inputSchema: {
			query: z.string().describe("The search query"),
			limit: z
				.number()
				.min(1)
				.max(100)
				.default(10)
				.describe("Maximum number of results to return"),
			category: z
				.enum(["docs", "blog", "api"])
				.optional()
				.describe("Filter by content category"),
		},
	},
	async ({ query, limit, category }) => {
		const results = await searchIndex(query, { limit, category });
		return {
			content: [{ type: "text", text: JSON.stringify(results) }],
		};
	},
);
server.registerTool(
	"search",
	{
		description: "Search for documents by query",
		inputSchema: {
			query: z.string().describe("The search query"),
			limit: z
				.number()
				.min(1)
				.max(100)
				.default(10)
				.describe("Maximum number of results to return"),
			category: z
				.enum(["docs", "blog", "api"])
				.optional()
				.describe("Filter by content category"),
		},
	},
	async ({ query, limit, category }) => {
		const results = await searchIndex(query, { limit, category });
		return {
			content: [{ type: "text", text: JSON.stringify(results) }],
		};
	},
);

Používání nástrojů s createMcpHandler

U bezstavových serverů MCP definujte nástroje uvnitř tovární funkce a server předejte createMcpHandler:

import { createMcpHandler } from "agents/mcp/server";
import { McpServer } from "@modelcontextprotocol/server";
import { z } from "zod";

function createServer() {
	const server = new McpServer({ name: "My Tools", version: "1.0.0" });

	server.registerTool(
		"ping",
		{ description: "Check if the server is alive", inputSchema: {} },
		async () => ({
			content: [{ type: "text", text: "pong" }],
		}),
	);

	return server;
}

export default {
	fetch(request, env, ctx) {
		return createMcpHandler(createServer)(request, env, ctx);
	},
};
import { createMcpHandler } from "agents/mcp/server";
import { McpServer } from "@modelcontextprotocol/server";
import { z } from "zod";

function createServer() {
	const server = new McpServer({ name: "My Tools", version: "1.0.0" });

	server.registerTool(
		"ping",
		{ description: "Check if the server is alive", inputSchema: {} },
		async () => ({
			content: [{ type: "text", text: "pong" }],
		}),
	);

	return server;
}

export default {
	fetch(request, env, ctx) {
		return createMcpHandler(createServer)(request, env, ctx);
	},
} satisfies ExportedHandler;

Používání nástrojů s McpAgent

Tato část se týká pouze existujících starších tras během migrace. Jejich nástroje definujte v init() metoda objektu McpAgent. Nástroje mají přístup k instanci agenta prostřednictvím this, takže mohou stav číst i zapisovat.

import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

export class MyMCP extends McpAgent {
	server = new McpServer({ name: "Stateful Tools", version: "1.0.0" });

	async init() {
		this.server.tool(
			"incrementCounter",
			"Increment and return a counter",
			{},
			async () => {
				const count = (this.state?.count ?? 0) + 1;
				this.setState({ count });
				return {
					content: [{ type: "text", text: `Counter: ${count}` }],
				};
			},
		);
	}
}
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

export class MyMCP extends McpAgent {
	server = new McpServer({ name: "Stateful Tools", version: "1.0.0" });

	async init() {
		this.server.tool(
			"incrementCounter",
			"Increment and return a counter",
			{},
			async () => {
				const count = (this.state?.count ?? 0) + 1;
				this.setState({ count });
				return {
					content: [{ type: "text", text: `Counter: ${count}` }],
				};
			},
		);
	}
}

Další kroky

Sestavte vzdálený server MCP

Podrobný návod krok za krokem k nasazení serveru MCP na Cloudflare.

createMcpHandler API

Reference pro bezstavové MCP servery.

McpAgent API

Reference pro stavové MCP servery.

Autorizace MCP

Přidejte do svého serveru MCP autentizaci OAuth.