From 308bdbc7c99ea18f946c7b630c12d296a540eac4 Mon Sep 17 00:00:00 2001
From: GHX5T-SOL <200635707+GHX5T-SOL@users.noreply.github.com>
Date: Mon, 18 May 2026 15:05:42 +0200
Subject: [PATCH 1/2] Fix MCP exec permission display metadata
---
.../components/permissions/McpPermission.tsx | 23 ++++++++--
.../permissions/PermissionSelector.test.tsx | 42 +++++++++++++++++++
.../permissions/PermissionSelector.tsx | 4 +-
.../permissions/permission-handlers.test.ts | 27 ++++++++++++
.../claude/permissions/permission-handlers.ts | 1 +
5 files changed, 91 insertions(+), 6 deletions(-)
create mode 100644 apps/code/src/renderer/components/permissions/PermissionSelector.test.tsx
diff --git a/apps/code/src/renderer/components/permissions/McpPermission.tsx b/apps/code/src/renderer/components/permissions/McpPermission.tsx
index 375926665..0f272a83b 100644
--- a/apps/code/src/renderer/components/permissions/McpPermission.tsx
+++ b/apps/code/src/renderer/components/permissions/McpPermission.tsx
@@ -8,7 +8,24 @@ import {
import { formatInput } from "@features/sessions/components/session-update/toolCallUtils";
import { Box, Code } from "@radix-ui/themes";
import { DefaultPermission } from "./DefaultPermission";
-import { type BasePermissionProps, toSelectorOptions } from "./types";
+import {
+ type BasePermissionProps,
+ type PermissionToolCall,
+ toSelectorOptions,
+} from "./types";
+
+export function getMcpPermissionToolName(
+ toolCall: PermissionToolCall,
+): string | undefined {
+ const metaToolName = (
+ toolCall._meta as { claudeCode?: { toolName?: unknown } } | undefined
+ )?.claudeCode?.toolName;
+ if (typeof metaToolName === "string") return metaToolName;
+
+ const rawToolName = (toolCall.rawInput as { toolName?: unknown } | undefined)
+ ?.toolName;
+ return typeof rawToolName === "string" ? rawToolName : undefined;
+}
export function McpPermission({
toolCall,
@@ -16,9 +33,7 @@ export function McpPermission({
onSelect,
onCancel,
}: BasePermissionProps) {
- const mcpToolName = (
- toolCall._meta as { claudeCode?: { toolName?: string } } | undefined
- )?.claudeCode?.toolName;
+ const mcpToolName = getMcpPermissionToolName(toolCall);
if (!mcpToolName) {
return (
diff --git a/apps/code/src/renderer/components/permissions/PermissionSelector.test.tsx b/apps/code/src/renderer/components/permissions/PermissionSelector.test.tsx
new file mode 100644
index 000000000..ace911295
--- /dev/null
+++ b/apps/code/src/renderer/components/permissions/PermissionSelector.test.tsx
@@ -0,0 +1,42 @@
+import { Theme } from "@radix-ui/themes";
+import { render, screen } from "@testing-library/react";
+import { describe, expect, it, vi } from "vitest";
+import { PermissionSelector } from "./PermissionSelector";
+
+describe("PermissionSelector", () => {
+ it("renders MCP permissions from rawInput toolName when metadata is missing", () => {
+ render(
+
+
+ ,
+ );
+
+ expect(
+ screen.getByText(
+ (_, element) =>
+ element?.textContent === "posthog - Read execute-sql (MCP)",
+ ),
+ ).toBeInTheDocument();
+ expect(screen.queryByText(/^exec$/)).not.toBeInTheDocument();
+ });
+});
diff --git a/apps/code/src/renderer/components/permissions/PermissionSelector.tsx b/apps/code/src/renderer/components/permissions/PermissionSelector.tsx
index b89ad00d0..81d499e2b 100644
--- a/apps/code/src/renderer/components/permissions/PermissionSelector.tsx
+++ b/apps/code/src/renderer/components/permissions/PermissionSelector.tsx
@@ -4,7 +4,7 @@ import { DeletePermission } from "./DeletePermission";
import { EditPermission } from "./EditPermission";
import { ExecutePermission } from "./ExecutePermission";
import { FetchPermission } from "./FetchPermission";
-import { McpPermission } from "./McpPermission";
+import { getMcpPermissionToolName, McpPermission } from "./McpPermission";
import { MovePermission } from "./MovePermission";
import { QuestionPermission } from "./QuestionPermission";
import { ReadPermission } from "./ReadPermission";
@@ -34,7 +34,7 @@ export function PermissionSelector({
const meta = toolCall._meta as
| { codeToolKind?: string; claudeCode?: { toolName?: string } }
| undefined;
- const agentToolName = meta?.claudeCode?.toolName;
+ const agentToolName = getMcpPermissionToolName(toolCall);
if (agentToolName?.startsWith("mcp__")) {
return ;
}
diff --git a/packages/agent/src/adapters/claude/permissions/permission-handlers.test.ts b/packages/agent/src/adapters/claude/permissions/permission-handlers.test.ts
index 15a3ee00b..dfcc425b1 100644
--- a/packages/agent/src/adapters/claude/permissions/permission-handlers.test.ts
+++ b/packages/agent/src/adapters/claude/permissions/permission-handlers.test.ts
@@ -74,6 +74,33 @@ describe("canUseTool MCP approval enforcement", () => {
expect.objectContaining({
toolCall: expect.objectContaining({
title: "The agent wants to call search_crm_objects (HubSpot)",
+ _meta: {
+ claudeCode: { toolName: "mcp__HubSpot__search_crm_objects" },
+ },
+ }),
+ }),
+ );
+ });
+
+ it("passes metadata through generic PostHog exec approval requests", async () => {
+ setMcpToolApprovalStates({
+ mcp__posthog__exec: "needs_approval",
+ });
+
+ const context = createContext("mcp__posthog__exec", {
+ toolInput: { command: "info execute-sql" },
+ });
+ const result = await canUseTool(context);
+
+ expect(result.behavior).toBe("allow");
+ expect(context.client.requestPermission).toHaveBeenCalledWith(
+ expect.objectContaining({
+ toolCall: expect.objectContaining({
+ rawInput: expect.objectContaining({
+ command: "info execute-sql",
+ toolName: "mcp__posthog__exec",
+ }),
+ _meta: { claudeCode: { toolName: "mcp__posthog__exec" } },
}),
}),
);
diff --git a/packages/agent/src/adapters/claude/permissions/permission-handlers.ts b/packages/agent/src/adapters/claude/permissions/permission-handlers.ts
index ec071bd93..6d1075b46 100644
--- a/packages/agent/src/adapters/claude/permissions/permission-handlers.ts
+++ b/packages/agent/src/adapters/claude/permissions/permission-handlers.ts
@@ -457,6 +457,7 @@ async function handleMcpApprovalFlow(
? [{ type: "content" as const, content: text(description) }]
: [],
rawInput: { ...(toolInput as Record), toolName },
+ _meta: { claudeCode: { toolName } },
},
});
From 1e63cce2637ccdd087b9778dc3119210821e2222 Mon Sep 17 00:00:00 2001
From: GHX5T-SOL <200635707+GHX5T-SOL@users.noreply.github.com>
Date: Mon, 18 May 2026 15:19:01 +0200
Subject: [PATCH 2/2] Simplify MCP permission selector metadata type
---
.../renderer/components/permissions/PermissionSelector.tsx | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/apps/code/src/renderer/components/permissions/PermissionSelector.tsx b/apps/code/src/renderer/components/permissions/PermissionSelector.tsx
index 81d499e2b..c571e6150 100644
--- a/apps/code/src/renderer/components/permissions/PermissionSelector.tsx
+++ b/apps/code/src/renderer/components/permissions/PermissionSelector.tsx
@@ -31,9 +31,7 @@ export function PermissionSelector({
onCancel,
}: PermissionSelectorProps) {
const props = { toolCall, options, onSelect, onCancel };
- const meta = toolCall._meta as
- | { codeToolKind?: string; claudeCode?: { toolName?: string } }
- | undefined;
+ const meta = toolCall._meta as { codeToolKind?: string } | undefined;
const agentToolName = getMcpPermissionToolName(toolCall);
if (agentToolName?.startsWith("mcp__")) {
return ;