mirror of
https://github.com/agentclientprotocol/claude-agent-acp.git
synced 2026-10-27 04:30:59 +00:00
Read file tool
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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 +
|
||||
`
|
||||
|
||||
<system-reminder>
|
||||
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.
|
||||
</system-reminder>`,
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
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 {
|
||||
|
||||
26
src/tools.ts
26
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 [
|
||||
|
||||
Reference in New Issue
Block a user