From b38ee5bfdfa6dd2902c13b84d7debf5360861390 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 27 Aug 2025 12:27:49 -0600 Subject: [PATCH] Read file tool --- src/acp-agent.ts | 78 ++--------------------------------------------- src/mcp-server.ts | 61 ++++++++++++++++++++++++++++++++++-- src/tools.ts | 26 ++++++++++++++-- 3 files changed, 84 insertions(+), 81 deletions(-) diff --git a/src/acp-agent.ts b/src/acp-agent.ts index bc91279a..219d833d 100644 --- a/src/acp-agent.ts +++ b/src/acp-agent.ts @@ -90,6 +90,8 @@ export class ClaudeAcpAgent implements Agent { cwd: params.cwd, mcpServers, executableArgs: ["--debug"], + allowedTools: ["mcp__acp__read"], + disallowedTools: ["Read"], strictMcpConfig: true, permissionPromptToolName: "mcp__acp__permission", stderr: (err) => console.error(err), @@ -266,82 +268,6 @@ export function toAcpNotifications( }; break; case "tool_use": - // { - // "type": "assistant", - // "message": { - // "id": "msg_017eNosJgww7F5qD4a8BcAcx", - // "type": "message", - // "role": "assistant", - // "model": "claude-sonnet-4-20250514", - // "content": [ - // { - // "type": "tool_use", - // "id": "toolu_01HaXZ4LfdchSeSR8ygt4zyq", - // "name": "TodoWrite", - // "input": { - // "todos": [ - // { - // "content": "Analyze existing test coverage and identify gaps", - // "status": "in_progress", - // "activeForm": "Analyzing existing test coverage" - // }, - // { - // "content": "Add comprehensive edge case tests", - // "status": "pending", - // "activeForm": "Adding comprehensive edge case tests" - // }, - // { - // "content": "Add performance and timing tests", - // "status": "pending", - // "activeForm": "Adding performance and timing tests" - // }, - // { - // "content": "Add error handling and panic behavior tests", - // "status": "pending", - // "activeForm": "Adding error handling tests" - // }, - // { - // "content": "Add concurrent access and race condition tests", - // "status": "pending", - // "activeForm": "Adding concurrent access tests" - // }, - // { - // "content": "Add tests for Each function with various data types", - // "status": "pending", - // "activeForm": "Adding Each function tests" - // }, - // { - // "content": "Add benchmark tests for performance measurement", - // "status": "pending", - // "activeForm": "Adding benchmark tests" - // }, - // { - // "content": "Improve test organization and helper functions", - // "status": "pending", - // "activeForm": "Improving test organization" - // } - // ] - // } - // } - // ], - // "stop_reason": null, - // "stop_sequence": null, - // "usage": { - // "input_tokens": 6, - // "cache_creation_input_tokens": 326, - // "cache_read_input_tokens": 17265, - // "cache_creation": { - // "ephemeral_5m_input_tokens": 326, - // "ephemeral_1h_input_tokens": 0 - // }, - // "output_tokens": 1, - // "service_tier": "standard" - // } - // }, - // "parent_tool_use_id": null, - // "session_id": "d056596f-e328-41e9-badd-b07122ae5227", - // "uuid": "b7c3330c-de8f-4bba-ac53-68c7f76ffeb5" - // } if (chunk.name == "TodoWrite") { update = { sessionUpdate: "plan", diff --git a/src/mcp-server.ts b/src/mcp-server.ts index aed8f572..9915f789 100644 --- a/src/mcp-server.ts +++ b/src/mcp-server.ts @@ -16,7 +16,65 @@ export function createMcpServer( version: "1.0.0", }); - // Register a simple echo tool (for demonstration) + server.registerTool( + "read", + { + title: "Read File", + description: ` + In sessions with 'mcp__acp__read' tool. Always use it instead of the 'Read' tool. The 'Read' tool is disabled. + + The offset parameter is the line to start at (omit to start at the first line) + The limit parameter is the number of lines to read (omit to read all lines) + `, + + inputSchema: { + abs_path: z.string(), + offset: z.number().optional(), + limit: z.number().optional(), + }, + }, + async (input) => { + console.error("READ TOOL", input); + const session = agent.sessions[sessionId]; + if (!session) { + return { + content: [ + { + type: "text", + text: "The user has left the building", + }, + ], + }; + } + let content = await agent.client.readTextFile({ + sessionId, + path: input.abs_path, + limit: input.limit, + line: input.offset, + }); + if (!input.limit) { + throw new Error( + "Reading the file failed because it's too large. Try the first 10 lines", + ); + } + + return { + content: [ + { + type: "text", + text: + content + + ` + + + Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior. + `, + }, + ], + }; + }, + ); + server.registerTool( "permission", { @@ -29,7 +87,6 @@ export function createMcpServer( }, }, async (input) => { - console.error("PERMISSION TOOl", input); const session = agent.sessions[sessionId]; if (!session) { return { diff --git a/src/tools.ts b/src/tools.ts index ba7a9aff..d942279e 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -22,17 +22,22 @@ export function toolLabel(toolUse: any): string { case "Terminal": case "Bash": return input?.command ?? "Terminal"; - case "ReadFile": + case "mcp__acp__read": + return "Read " + (input.abs_path ?? "File"); + case "Read": return "Read File"; case "LS": return input?.path ? `List Directory ${input.path}` : "List Directory"; + case "mcp__zed__Edit": case "Edit": return input?.abs_path ? `Edit ${input.abs_path}` : "Edit"; case "MultiEdit": return input?.file_path ? `Multi Edit ${input.file_path}` : "Multi Edit"; + case "mcp__zed__Write": case "Write": return input?.abs_path ? `Write ${input.abs_path}` : "Write"; case "Glob": + // todo!() don't render object return input ? `Glob \`${input}\`` : "Glob"; case "Grep": return input ? `\`${input}\`` : "Grep"; @@ -59,13 +64,16 @@ export function toolKind(toolName: string): ToolKind { return "read"; case "NotebookEdit": return "edit"; + case "mcp__zed__Edit": case "Edit": return "edit"; case "MultiEdit": return "edit"; + case "mcp__zed__Write": case "Write": return "edit"; - case "ReadFile": + case "mcp__acp__read": + case "Read": return "read"; case "LS": return "search"; @@ -144,7 +152,17 @@ export function toolContent(toolUse: any): ToolCallContent[] { ]; } break; - case "ReadFile": + case "mcp__acp__read": + if (toolUse.content) { + return [ + { + type: "content", + content: { type: "text", text: toolUse.content }, + }, + ]; + } + break; + case "Read": if (input && input.abs_path) { return [ { @@ -205,6 +223,7 @@ export function toolContent(toolUse: any): ToolCallContent[] { ]; } break; + case "mcp__zed__Edit": case "Edit": if (input && input.abs_path) { return [ @@ -217,6 +236,7 @@ export function toolContent(toolUse: any): ToolCallContent[] { ]; } break; + case "mcp__zed__Write": case "Write": if (input && input.abs_path) { return [