mirror of
https://github.com/agentclientprotocol/claude-agent-acp.git
synced 2026-10-27 04:30:59 +00:00
Working permissions
This commit is contained in:
@@ -34,7 +34,7 @@ import { createMcpServer } from "./mcp-server.js";
|
||||
import { AddressInfo } from "node:net";
|
||||
|
||||
// Implement the ACP Agent interface
|
||||
class ClaudeAcpAgent implements Agent {
|
||||
export class ClaudeAcpAgent implements Agent {
|
||||
sessions: {
|
||||
[key: string]: { query: Query; input: Pushable<SDKUserMessage> };
|
||||
};
|
||||
@@ -70,7 +70,7 @@ class ClaudeAcpAgent implements Agent {
|
||||
}
|
||||
|
||||
// todo!() auth, permissionPromptToolName
|
||||
let server = await createMcpServer();
|
||||
let server = await createMcpServer(this, sessionId);
|
||||
let address = server.address() as AddressInfo;
|
||||
mcpServers["acp"] = {
|
||||
type: "http",
|
||||
@@ -292,6 +292,68 @@ function toAcpNotifications(
|
||||
|
||||
return output;
|
||||
}
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: "content": [
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: {
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: "type": "tool_use",
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: "id": "toolu_01BZ6ZfAoU5Vw1g4YiRa8kv3",
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: "name": "Bash",
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: "input": {
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: "command": "rm README.md.es",
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: "description": "Delete README.md.es file"
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: }
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: }
|
||||
2025-08-27T11:10:22-06:00 WARN [agent_servers::acp] agent stderr: ],
|
||||
|
||||
pub fn label(&self) -> String {
|
||||
match &self {
|
||||
Self::Task(Some(params)) => params.description.clone(),
|
||||
Self::Task(None) => "Task".into(),
|
||||
Self::NotebookRead(Some(params)) => {
|
||||
format!("Read Notebook {}", params.notebook_path.display())
|
||||
}
|
||||
Self::NotebookRead(None) => "Read Notebook".into(),
|
||||
Self::NotebookEdit(Some(params)) => {
|
||||
format!("Edit Notebook {}", params.notebook_path.display())
|
||||
}
|
||||
Self::NotebookEdit(None) => "Edit Notebook".into(),
|
||||
Self::Terminal(Some(params)) => format!("`{}`", params.command),
|
||||
Self::Terminal(None) => "Terminal".into(),
|
||||
Self::ReadFile(_) => "Read File".into(),
|
||||
Self::Ls(Some(params)) => {
|
||||
format!("List Directory {}", params.path.display())
|
||||
}
|
||||
Self::Ls(None) => "List Directory".into(),
|
||||
Self::Edit(Some(params)) => {
|
||||
format!("Edit {}", params.abs_path.display())
|
||||
}
|
||||
Self::Edit(None) => "Edit".into(),
|
||||
Self::MultiEdit(Some(params)) => {
|
||||
format!("Multi Edit {}", params.file_path.display())
|
||||
}
|
||||
Self::MultiEdit(None) => "Multi Edit".into(),
|
||||
Self::Write(Some(params)) => {
|
||||
format!("Write {}", params.abs_path.display())
|
||||
}
|
||||
Self::Write(None) => "Write".into(),
|
||||
Self::Glob(Some(params)) => {
|
||||
format!("Glob `{params}`")
|
||||
}
|
||||
Self::Glob(None) => "Glob".into(),
|
||||
Self::Grep(Some(params)) => format!("`{params}`"),
|
||||
Self::Grep(None) => "Grep".into(),
|
||||
Self::WebFetch(Some(params)) => format!("Fetch {}", params.url),
|
||||
Self::WebFetch(None) => "Fetch".into(),
|
||||
Self::WebSearch(Some(params)) => format!("Web Search: {}", params),
|
||||
Self::WebSearch(None) => "Web Search".into(),
|
||||
Self::TodoWrite(Some(params)) => format!(
|
||||
"Update TODOs: {}",
|
||||
params.todos.iter().map(|todo| &todo.content).join(", ")
|
||||
),
|
||||
Self::TodoWrite(None) => "Update TODOs".into(),
|
||||
Self::ExitPlanMode(_) => "Exit Plan Mode".into(),
|
||||
Self::Other { name, .. } => name.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
export function runAcp() {
|
||||
new AgentSideConnection(
|
||||
|
||||
@@ -4,8 +4,12 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
||||
import { z } from "zod";
|
||||
import { Server } from "node:http";
|
||||
import { ClaudeAcpAgent } from "./acp-agent.js";
|
||||
|
||||
export function createMcpServer(): Promise<Server> {
|
||||
export function createMcpServer(
|
||||
agent: ClaudeAcpAgent,
|
||||
sessionId: string,
|
||||
): Promise<Server> {
|
||||
// Create MCP server
|
||||
const server = new McpServer({
|
||||
name: "acp-mcp-server",
|
||||
@@ -26,17 +30,59 @@ export function createMcpServer(): Promise<Server> {
|
||||
},
|
||||
async (input) => {
|
||||
console.error("PERMISSION TOOl", input);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
behavior: "allow",
|
||||
updatedInput: input.input,
|
||||
}),
|
||||
},
|
||||
const session = agent.sessions[sessionId];
|
||||
if (!session) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
behavior: "deny",
|
||||
message: "Session not found",
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
let response = await agent.client.requestPermission({
|
||||
options: [
|
||||
{ kind: "allow_once", name: "Allow", optionId: "allow" },
|
||||
{ kind: "reject_once", name: "Reject", optionId: "reject" },
|
||||
],
|
||||
};
|
||||
sessionId,
|
||||
toolCall: {
|
||||
toolCallId: input.tool_use_id!,
|
||||
rawInput: input.input,
|
||||
},
|
||||
});
|
||||
if (
|
||||
response.outcome?.outcome == "selected" &&
|
||||
response.outcome.optionId == "allow"
|
||||
) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
behavior: "allow",
|
||||
updatedInput: input.input,
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: JSON.stringify({
|
||||
behavior: "deny",
|
||||
message: "User refused permission to run tool",
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user