// File management MCP tools
import { z } from 'zod';
import type { DriveService } from '../services/drive.js';
// ─────────────────────────────────────────────────────────────────────────────
// SCHEMAS
// ─────────────────────────────────────────────────────────────────────────────
export const SearchSchema = z.object({
query: z.string().describe('Search query (Google Drive query syntax)'),
pageSize: z.number().optional().default(10).describe('Number of results (max 100)'),
pageToken: z.string().optional().describe('Token for pagination'),
});
export const CreateTextFileSchema = z.object({
name: z.string().describe('File name with extension (.txt, .md, etc)'),
content: z.string().describe('File content'),
folder: z.string().optional().describe('Parent folder ID or path (e.g., /Projects/2025)'),
});
export const UpdateTextFileSchema = z.object({
fileId: z.string().describe('ID of the file to update'),
content: z.string().describe('New file content'),
});
export const DeleteFileSchema = z.object({
fileId: z.string().describe('ID of the file to delete'),
});
export const RenameFileSchema = z.object({
fileId: z.string().describe('ID of the file to rename'),
newName: z.string().describe('New file name'),
});
export const MoveFileSchema = z.object({
fileId: z.string().describe('ID of the file to move'),
destinationFolder: z.string().describe('Destination folder ID or path'),
});
export const CopyFileSchema = z.object({
fileId: z.string().describe('ID of the file to copy'),
newName: z.string().optional().describe('Name for the copy'),
destinationFolder: z.string().optional().describe('Destination folder ID or path'),
});
// ─────────────────────────────────────────────────────────────────────────────
// TOOL DEFINITIONS
// ─────────────────────────────────────────────────────────────────────────────
export const fileTools = [
{
name: 'search',
description: 'Search for files in Google Drive using query syntax',
inputSchema: {
type: 'object' as const,
properties: {
query: { type: 'string', description: 'Search query (Google Drive query syntax)' },
pageSize: { type: 'number', description: 'Number of results (max 100)' },
pageToken: { type: 'string', description: 'Token for pagination' },
},
required: ['query'],
},
},
{
name: 'createTextFile',
description: 'Create a new text file (.txt, .md, .json, etc) in Google Drive',
inputSchema: {
type: 'object' as const,
properties: {
name: { type: 'string', description: 'File name with extension' },
content: { type: 'string', description: 'File content' },
folder: { type: 'string', description: 'Parent folder ID or path' },
},
required: ['name', 'content'],
},
},
{
name: 'updateTextFile',
description: 'Update the content of an existing text file',
inputSchema: {
type: 'object' as const,
properties: {
fileId: { type: 'string', description: 'ID of the file to update' },
content: { type: 'string', description: 'New file content' },
},
required: ['fileId', 'content'],
},
},
{
name: 'deleteFile',
description: 'Delete a file from Google Drive (moves to trash)',
inputSchema: {
type: 'object' as const,
properties: {
fileId: { type: 'string', description: 'ID of the file to delete' },
},
required: ['fileId'],
},
},
{
name: 'renameFile',
description: 'Rename a file in Google Drive',
inputSchema: {
type: 'object' as const,
properties: {
fileId: { type: 'string', description: 'ID of the file to rename' },
newName: { type: 'string', description: 'New file name' },
},
required: ['fileId', 'newName'],
},
},
{
name: 'moveFile',
description: 'Move a file to a different folder',
inputSchema: {
type: 'object' as const,
properties: {
fileId: { type: 'string', description: 'ID of the file to move' },
destinationFolder: { type: 'string', description: 'Destination folder ID or path' },
},
required: ['fileId', 'destinationFolder'],
},
},
{
name: 'copyFile',
description: 'Create a copy of a file',
inputSchema: {
type: 'object' as const,
properties: {
fileId: { type: 'string', description: 'ID of the file to copy' },
newName: { type: 'string', description: 'Name for the copy' },
destinationFolder: { type: 'string', description: 'Destination folder ID or path' },
},
required: ['fileId'],
},
},
];
// ─────────────────────────────────────────────────────────────────────────────
// HANDLERS
// ─────────────────────────────────────────────────────────────────────────────
export function createFileHandlers(driveService: DriveService) {
return {
search: async (args: z.infer<typeof SearchSchema>) => {
const params = SearchSchema.parse(args);
return driveService.search(params.query, params.pageSize, params.pageToken);
},
createTextFile: async (args: z.infer<typeof CreateTextFileSchema>) => {
const params = CreateTextFileSchema.parse(args);
return driveService.createTextFile(params.name, params.content, params.folder);
},
updateTextFile: async (args: z.infer<typeof UpdateTextFileSchema>) => {
const params = UpdateTextFileSchema.parse(args);
return driveService.updateTextFile(params.fileId, params.content);
},
deleteFile: async (args: z.infer<typeof DeleteFileSchema>) => {
const params = DeleteFileSchema.parse(args);
return driveService.deleteFile(params.fileId);
},
renameFile: async (args: z.infer<typeof RenameFileSchema>) => {
const params = RenameFileSchema.parse(args);
return driveService.renameFile(params.fileId, params.newName);
},
moveFile: async (args: z.infer<typeof MoveFileSchema>) => {
const params = MoveFileSchema.parse(args);
return driveService.moveFile(params.fileId, params.destinationFolder);
},
copyFile: async (args: z.infer<typeof CopyFileSchema>) => {
const params = CopyFileSchema.parse(args);
return driveService.copyFile(params.fileId, params.newName, params.destinationFolder);
},
};
}