Skip to content

Commit 5856737

Browse files
author
BrokenDuck
committed
Add delete file tool
1 parent 13e74f4 commit 5856737

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

mcp-run-python/src/files.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,27 @@ export function registerFileFunctions(server: McpServer, rootDir: string) {
110110
}
111111
}
112112
})
113+
114+
// File deletion
115+
server.registerTool('delete_file', {
116+
title: 'Delete a file',
117+
description: 'Delete a file from the persistent file store.',
118+
inputSchema: { filename: z.string().describe('The name of the file to delete.') },
119+
}, async ({ filename }) => {
120+
const absPath = path.join(rootDir, filename)
121+
if (await exists(absPath, { isFile: true })) {
122+
await Deno.remove(absPath)
123+
return {
124+
content: [{
125+
type: 'text',
126+
text: `${filename} deleted successfully`,
127+
}],
128+
}
129+
} else {
130+
return {
131+
content: [{ 'type': 'text', 'text': `Failed to delete file ${filename}. File not found.` }],
132+
isError: true,
133+
}
134+
}
135+
})
113136
}

mcp-run-python/test_mcp_servers.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class McpTools(StrEnum):
4141
RUN_PYTHON_CODE = 'run_python_code'
4242
UPLOAD_FILE_FROM_URI = 'upload_file_from_uri'
4343
RETRIEVE_FILE = 'retrieve_file'
44+
DELETE_FILE = 'delete_file'
4445

4546

4647
CSV_DATA = """Name,Age,Department,Salary
@@ -168,10 +169,15 @@ async def test_list_tools(
168169
)
169170
else:
170171
# Check tools
171-
assert len(tools.tools) == 3
172+
assert len(tools.tools) == 4
172173
# sort tools by their name
173174
sorted_tools = sorted(tools.tools, key=lambda t: t.name)
174-
tool = sorted_tools[1]
175+
176+
# Check tool names
177+
assert set(tool.name for tool in tools.tools) == set(McpTools)
178+
179+
# Check run python tool
180+
tool = sorted_tools[2]
175181
assert tool.name == McpTools.RUN_PYTHON_CODE
176182
assert tool.description
177183
assert tool.description.startswith(
@@ -180,6 +186,7 @@ async def test_list_tools(
180186
assert tool.inputSchema['properties'] == snapshot(
181187
{'python_code': {'type': 'string', 'description': 'Python code to run'}}
182188
)
189+
183190
# Check resources (no file uploaded)
184191
resources = await mcp_session.list_resources()
185192
assert len(resources.resources) == 0
@@ -451,6 +458,32 @@ async def test_download_files(
451458
assert isinstance(resource, types.TextResourceContents)
452459
assert resource.text == CSV_DATA
453460

461+
async def test_delete_file(
462+
self,
463+
mcp_session: ClientSession,
464+
server_type: Literal['stdio', 'sse', 'streamable_http'],
465+
mount: bool | str,
466+
):
467+
if mount is False:
468+
pytest.skip('No directory mounted.')
469+
result = await mcp_session.initialize()
470+
471+
# Extract directory from response
472+
storageDir = self.get_dir_from_instructions(result.instructions)
473+
assert storageDir.is_dir()
474+
475+
filename = 'data.csv'
476+
file_path = storageDir / filename
477+
file_path.write_text(CSV_DATA)
478+
479+
result = await mcp_session.call_tool(McpTools.DELETE_FILE, {'filename': filename})
480+
assert result.isError is False
481+
assert len(result.content) == 1
482+
content = result.content[0]
483+
assert isinstance(content, types.TextContent)
484+
assert content.text.endswith('deleted successfully')
485+
assert not file_path.exists()
486+
454487
# Code pieces use hardcoded values of mount
455488
@pytest.mark.parametrize(
456489
'code,expected_output,content_type',

0 commit comments

Comments
 (0)