Skip to content

Commit 847ec4c

Browse files
fix: update run_poc signature to take in a file path instead of source code to run.
1 parent d52c8ca commit 847ec4c

3 files changed

Lines changed: 31 additions & 39 deletions

File tree

mcp-server/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ server.tool(
5656
'run_poc',
5757
'Runs the generated PoC code.',
5858
{
59-
code: z.string().describe('The PoC code to run.'),
59+
filePath: z.string().describe('The absolute path to the PoC file to run.'),
6060
} as any,
61-
(input: { code: string }) => runPoc(input)
61+
(input: { filePath: string }) => runPoc(input)
6262
);
6363

6464
server.registerPrompt(

mcp-server/src/poc.test.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,44 +8,48 @@ import { describe, it, vi, expect } from 'vitest';
88
import { runPoc } from './poc.js';
99

1010
describe('runPoc', () => {
11-
it('should write file and execute it', async () => {
12-
const mockFs = {
13-
mkdir: vi.fn(async () => undefined),
14-
writeFile: vi.fn(async () => undefined),
15-
};
11+
it('should execute the file at the given path', async () => {
1612
const mockPath = {
17-
join: (...args: string[]) => args.join('/'),
13+
dirname: (p: string) => p.substring(0, p.lastIndexOf('/')),
1814
};
19-
const mockExecAsync = vi.fn(async () => ({ stdout: 'output', stderr: '' }));
15+
const mockExecAsync = vi.fn(async (cmd: string) => {
16+
if (cmd.startsWith('npm install')) {
17+
return { stdout: '', stderr: '' };
18+
}
19+
return { stdout: 'output', stderr: '' };
20+
});
2021

2122
const result = await runPoc(
22-
{ code: 'console.log("test")' },
23-
{ fs: mockFs as any, path: mockPath as any, execAsync: mockExecAsync as any }
23+
{ filePath: '/tmp/test.js' },
24+
{ fs: {} as any, path: mockPath as any, execAsync: mockExecAsync as any }
2425
);
2526

26-
expect(mockFs.mkdir).toHaveBeenCalledTimes(1);
27-
expect(mockFs.writeFile).toHaveBeenCalledTimes(1);
2827
expect(mockExecAsync).toHaveBeenCalledTimes(2);
28+
expect(mockExecAsync).toHaveBeenNthCalledWith(
29+
1,
30+
'npm install --registry=https://registry.npmjs.org/',
31+
{ cwd: '/tmp' }
32+
);
33+
expect(mockExecAsync).toHaveBeenNthCalledWith(2, 'node /tmp/test.js');
2934
expect((result.content[0] as any).text).toBe(
3035
JSON.stringify({ stdout: 'output', stderr: '' })
3136
);
3237
});
3338

3439
it('should handle execution errors', async () => {
35-
const mockFs = {
36-
mkdir: vi.fn(async () => undefined),
37-
writeFile: vi.fn(async () => undefined),
38-
};
3940
const mockPath = {
40-
join: (...args: string[]) => args.join('/'),
41+
dirname: (p: string) => p.substring(0, p.lastIndexOf('/')),
4142
};
42-
const mockExecAsync = vi.fn(async () => {
43-
throw new Error('Execution failed');
43+
const mockExecAsync = vi.fn(async (cmd: string) => {
44+
if (cmd.startsWith('node')) {
45+
throw new Error('Execution failed');
46+
}
47+
return { stdout: '', stderr: '' };
4448
});
4549

4650
const result = await runPoc(
47-
{ code: 'error' },
48-
{ fs: mockFs as any, path: mockPath as any, execAsync: mockExecAsync as any }
51+
{ filePath: '/tmp/error.js' },
52+
{ fs: {} as any, path: mockPath as any, execAsync: mockExecAsync as any }
4953
);
5054

5155
expect(result.isError).toBe(true);

mcp-server/src/poc.ts

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,22 @@ const execAsync = promisify(exec);
1414

1515
export async function runPoc(
1616
{
17-
code,
17+
filePath,
1818
}: {
19-
code: string;
19+
filePath: string;
2020
},
2121
dependencies: { fs: typeof fs; path: typeof path; execAsync: typeof execAsync } = { fs, path, execAsync }
2222
): Promise<CallToolResult> {
2323
try {
24-
const CWD = process.cwd();
25-
const securityDir = dependencies.path.join(CWD, '.gemini_security');
24+
const pocDir = dependencies.path.dirname(filePath);
2625

27-
// Ensure .gemini_security directory exists
2826
try {
29-
await dependencies.fs.mkdir(securityDir, { recursive: true });
30-
} catch (error) {
31-
// Ignore error if directory already exists
32-
}
33-
34-
const pocFilePath = dependencies.path.join(securityDir, 'poc.js');
35-
await dependencies.fs.writeFile(pocFilePath, code, 'utf-8');
36-
37-
38-
try {
39-
await dependencies.execAsync('npm install --registry=https://registry.npmjs.org/', { cwd: securityDir });
27+
await dependencies.execAsync('npm install --registry=https://registry.npmjs.org/', { cwd: pocDir });
4028
} catch (error) {
4129
// Ignore errors from npm install, as it might fail if no package.json exists,
4230
// but we still want to attempt running the PoC.
4331
}
44-
const { stdout, stderr } = await dependencies.execAsync(`node ${pocFilePath}`);
32+
const { stdout, stderr } = await dependencies.execAsync(`node ${filePath}`);
4533

4634
return {
4735
content: [

0 commit comments

Comments
 (0)