make mcp e2e test claude permissions
This commit is contained in:
@@ -66,26 +66,16 @@ async function waitForFile(filePath: string, timeoutMs = 30000): Promise<string>
|
|||||||
throw new Error(`Timed out waiting for ${filePath}`);
|
throw new Error(`Timed out waiting for ${filePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function settleAgentRun(client: McpClient, agentId: string): Promise<void> {
|
async function waitForAgentCompletion(
|
||||||
|
client: McpClient,
|
||||||
|
agentId: string
|
||||||
|
): Promise<void> {
|
||||||
for (let attempt = 0; attempt < 6; attempt += 1) {
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
||||||
const waitResult = (await client.callTool({
|
const waitResult = (await client.callTool({
|
||||||
name: "wait_for_agent",
|
name: "wait_for_agent",
|
||||||
args: { agentId },
|
args: { agentId },
|
||||||
})) as McpToolResult;
|
})) as McpToolResult;
|
||||||
const payload = getStructuredContent(waitResult);
|
const payload = getStructuredContent(waitResult);
|
||||||
const permission = payload?.permission as PermissionPayload | null | undefined;
|
|
||||||
if (permission?.id) {
|
|
||||||
await client.callTool({
|
|
||||||
name: "respond_to_permission",
|
|
||||||
args: {
|
|
||||||
agentId,
|
|
||||||
requestId: permission.id,
|
|
||||||
response: { behavior: "allow" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const status = payload?.status;
|
const status = payload?.status;
|
||||||
if (status && status !== "running" && status !== "initializing") {
|
if (status && status !== "running" && status !== "initializing") {
|
||||||
return;
|
return;
|
||||||
@@ -98,19 +88,11 @@ async function settleAgentRun(client: McpClient, agentId: string): Promise<void>
|
|||||||
const hasClaudeCredentials = Boolean(
|
const hasClaudeCredentials = Boolean(
|
||||||
process.env.CLAUDE_CODE_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY
|
process.env.CLAUDE_CODE_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY
|
||||||
);
|
);
|
||||||
const hasCodexCredentials = Boolean(
|
|
||||||
process.env.OPENAI_API_KEY ||
|
|
||||||
process.env.CODEX_API_KEY ||
|
|
||||||
process.env.OPENROUTER_API_KEY
|
|
||||||
);
|
|
||||||
const hasAgentCredentials = hasClaudeCredentials || hasCodexCredentials;
|
|
||||||
const agentType = hasClaudeCredentials ? "claude" : "codex";
|
|
||||||
const agentMode = agentType === "claude" ? "bypassPermissions" : "full-access";
|
|
||||||
|
|
||||||
describe("agent MCP end-to-end", () => {
|
describe("agent MCP end-to-end", () => {
|
||||||
const runTest = hasAgentCredentials ? test : test.skip;
|
const runTest = hasClaudeCredentials ? test : test.skip;
|
||||||
runTest(
|
runTest(
|
||||||
"creates an agent and writes a file",
|
"creates a Claude agent and writes a file",
|
||||||
async () => {
|
async () => {
|
||||||
const paseoHome = await mkdtemp(path.join(os.tmpdir(), "paseo-home-"));
|
const paseoHome = await mkdtemp(path.join(os.tmpdir(), "paseo-home-"));
|
||||||
const staticDir = await mkdtemp(path.join(os.tmpdir(), "paseo-static-"));
|
const staticDir = await mkdtemp(path.join(os.tmpdir(), "paseo-static-"));
|
||||||
@@ -183,8 +165,8 @@ describe("agent MCP end-to-end", () => {
|
|||||||
args: {
|
args: {
|
||||||
cwd: agentCwd,
|
cwd: agentCwd,
|
||||||
title: "MCP e2e smoke",
|
title: "MCP e2e smoke",
|
||||||
agentType,
|
agentType: "claude",
|
||||||
initialMode: agentMode,
|
initialMode: "default",
|
||||||
background: false,
|
background: false,
|
||||||
},
|
},
|
||||||
})) as McpToolResult;
|
})) as McpToolResult;
|
||||||
@@ -195,34 +177,37 @@ describe("agent MCP end-to-end", () => {
|
|||||||
expect(agentId).toBeTruthy();
|
expect(agentId).toBeTruthy();
|
||||||
|
|
||||||
const prompt = [
|
const prompt = [
|
||||||
"Use a shell command to create ./mcp-smoke.txt.",
|
"You must call the tool named shell.",
|
||||||
"Write exactly ok (no quotes) into the file.",
|
"Run this command exactly: [\"bash\", \"-lc\", \"echo ok > mcp-smoke.txt\"].",
|
||||||
"Then reply with done and stop.",
|
"After the tool runs, reply with done and stop.",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
const promptResult = (await client.callTool({
|
await client.callTool({
|
||||||
name: "send_agent_prompt",
|
name: "send_agent_prompt",
|
||||||
args: {
|
args: {
|
||||||
agentId,
|
agentId,
|
||||||
prompt,
|
prompt,
|
||||||
sessionMode: agentMode,
|
sessionMode: "default",
|
||||||
background: false,
|
background: true,
|
||||||
},
|
},
|
||||||
})) as McpToolResult;
|
});
|
||||||
|
|
||||||
const promptPayload = getStructuredContent(promptResult);
|
const waitResult = (await client.callTool({
|
||||||
if (promptPayload?.permission) {
|
name: "wait_for_agent",
|
||||||
const permission = promptPayload.permission as PermissionPayload;
|
args: { agentId },
|
||||||
await client.callTool({
|
})) as McpToolResult;
|
||||||
name: "respond_to_permission",
|
const waitPayload = getStructuredContent(waitResult);
|
||||||
args: {
|
const permission = waitPayload?.permission as PermissionPayload | null;
|
||||||
agentId,
|
expect(permission?.id).toBeTruthy();
|
||||||
requestId: permission.id,
|
await client.callTool({
|
||||||
response: { behavior: "allow" },
|
name: "respond_to_permission",
|
||||||
},
|
args: {
|
||||||
});
|
agentId,
|
||||||
}
|
requestId: permission!.id,
|
||||||
await settleAgentRun(client, agentId);
|
response: { behavior: "allow" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await waitForAgentCompletion(client, agentId);
|
||||||
|
|
||||||
const filePath = path.join(agentCwd, "mcp-smoke.txt");
|
const filePath = path.join(agentCwd, "mcp-smoke.txt");
|
||||||
let contents: string;
|
let contents: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user