























11// Plugin MCP serve tests cover serving plugin tools over MCP.
2+import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3+import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
4+import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types.js";
25import { afterEach, describe, expect, it, vi } from "vitest";
36import {
47type HookContext,
@@ -180,6 +183,82 @@ describe("plugin tools MCP server", () => {
180183expect(result.content).toEqual([{ type: "text", text: "Stored." }]);
181184});
182185186+it("serializes source-shaped image tool content with pinned MCP image blocks", async () => {
187+const execute = vi.fn().mockResolvedValue({
188+content: [
189+{ type: "text", text: "browser screenshot" },
190+{
191+type: "image",
192+source: {
193+type: "base64",
194+media_type: "image/png",
195+data: "iVBORw0KGgo=",
196+},
197+},
198+],
199+});
200+const tool = {
201+name: "browser_screenshot",
202+description: "Capture a browser screenshot",
203+parameters: { type: "object", properties: {} },
204+ execute,
205+} as unknown as AnyAgentTool;
206+207+const handlers = createPluginToolsMcpHandlers([tool]);
208+const result = await handlers.callTool({
209+name: "browser_screenshot",
210+arguments: {},
211+});
212+213+expect(result.content).toEqual([
214+{ type: "text", text: "browser screenshot" },
215+{ type: "image", data: "iVBORw0KGgo=", mimeType: "image/png" },
216+]);
217+expect(() => CallToolResultSchema.parse(result)).not.toThrow();
218+});
219+220+it("delivers source-shaped images through a real MCP client", async () => {
221+const execute = vi.fn().mockResolvedValue({
222+content: [
223+{ type: "text", text: "browser screenshot" },
224+{
225+type: "image",
226+source: {
227+type: "base64",
228+media_type: "image/png",
229+data: "iVBORw0KGgo=",
230+},
231+},
232+],
233+});
234+const tool = {
235+name: "browser_screenshot",
236+description: "Capture a browser screenshot",
237+parameters: { type: "object", properties: {} },
238+ execute,
239+} as unknown as AnyAgentTool;
240+const { createToolsMcpServer } =
241+await vi.importActual<typeof import("./tools-stdio-server.js")>("./tools-stdio-server.js");
242+const server = createToolsMcpServer({ name: "plugin-tools-image-test", tools: [tool] });
243+const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
244+const client = new Client(
245+{ name: "plugin-tools-image-test-client", version: "0.0.0" },
246+{ capabilities: {} },
247+);
248+249+await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]);
250+try {
251+const result = await client.callTool({ name: "browser_screenshot", arguments: {} });
252+expect(result.content).toEqual([
253+{ type: "text", text: "browser screenshot" },
254+{ type: "image", data: "iVBORw0KGgo=", mimeType: "image/png" },
255+]);
256+} finally {
257+await client.close();
258+await server.close();
259+}
260+});
261+183262it("serializes plugin tool results that do not use the MCP content envelope", async () => {
184263const execute = vi.fn().mockResolvedValue({
185264provider: "kitchen-sink-search",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。