From bb3b6a2f65a3c95015fb2461e436288a316d7930 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Sat, 4 Jul 2026 20:47:33 -0400 Subject: [PATCH] fix(protocol): expose MCP tool change events (#35373) --- .../client/src/promise/generated/types.ts | 8 +++++++ packages/protocol/test/event.test.ts | 23 +++++++++++++++++++ packages/schema/src/event-manifest.ts | 2 +- packages/schema/test/event-manifest.test.ts | 1 + 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 packages/protocol/test/event.test.ts diff --git a/packages/client/src/promise/generated/types.ts b/packages/client/src/promise/generated/types.ts index 151f0ff03f..ba3c1a563b 100644 --- a/packages/client/src/promise/generated/types.ts +++ b/packages/client/src/promise/generated/types.ts @@ -5402,6 +5402,14 @@ export type EventSubscribeOutput = readonly location?: { readonly directory: string; readonly workspaceID?: string } readonly data: { readonly branch?: string } } + | { + readonly id: string + readonly created: number + readonly metadata?: { readonly [x: string]: unknown } + readonly type: "mcp.tools.changed" + readonly location?: { readonly directory: string; readonly workspaceID?: string } + readonly data: { readonly server: string } + } | { readonly id: string readonly created: number diff --git a/packages/protocol/test/event.test.ts b/packages/protocol/test/event.test.ts new file mode 100644 index 0000000000..52757ad30e --- /dev/null +++ b/packages/protocol/test/event.test.ts @@ -0,0 +1,23 @@ +import { expect, test } from "bun:test" +import { Event } from "@opencode-ai/schema/event" +import { AbsolutePath } from "@opencode-ai/schema/schema" +import { DateTime, Schema } from "effect" +import { OpenCodeEvent } from "../src/groups/event.js" + +test("encodes MCP tool changes emitted by the server", () => { + expect( + Schema.encodeSync(OpenCodeEvent)({ + id: Event.ID.make("evt_test"), + created: DateTime.makeUnsafe(0), + type: "mcp.tools.changed", + location: { directory: AbsolutePath.make("/tmp") }, + data: { server: "example" }, + }), + ).toEqual({ + id: "evt_test", + created: 0, + type: "mcp.tools.changed", + location: { directory: "/tmp" }, + data: { server: "example" }, + }) +}) diff --git a/packages/schema/src/event-manifest.ts b/packages/schema/src/event-manifest.ts index 6b2b806f81..09a5db8da4 100644 --- a/packages/schema/src/event-manifest.ts +++ b/packages/schema/src/event-manifest.ts @@ -78,7 +78,7 @@ export const ServerDefinitions = Event.inventory( ...TuiEvent.Definitions, ...InstallationEvent.Definitions, ...VcsEvent.Definitions, - McpEvent.StatusChanged, + ...McpEvent.Definitions, // Shared transitional: V1 contracts the current TUI still consumes during // the migration (permission.asked/replied, question.asked, session.error). // Remove when the TUI moves to the current permission/question surfaces. diff --git a/packages/schema/test/event-manifest.test.ts b/packages/schema/test/event-manifest.test.ts index 487a942d9a..22003313ba 100644 --- a/packages/schema/test/event-manifest.test.ts +++ b/packages/schema/test/event-manifest.test.ts @@ -27,6 +27,7 @@ describe("public event manifest", () => { Agent.Event.Updated, ]) expect(EventManifest.Definitions).toContain(Agent.Event.Updated) + expect(EventManifest.ServerDefinitions).toContain(McpEvent.ToolsChanged) expect(EventManifest.Definitions.filter((definition) => definition.type === "agent.updated")).toEqual([ Agent.Event.Updated, ])