File size: 2,639 Bytes
7dc28be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import type { FastMCP } from 'fastmcp';
import { UserError } from 'fastmcp';
import { z } from 'zod';
import { drive_v3 } from 'googleapis';
import { getDriveClient } from '../../clients.js';

export function register(server: FastMCP) {
  server.addTool({
    name: 'copyFile',
    description:
      "Creates a copy of a file or document in Google Drive. Returns the new copy's ID and URL.",
    parameters: z.strictObject({
      fileId: z
        .string()
        .describe('The file or folder ID from a Google Drive URL or a previous tool result.'),
      newName: z
        .string()
        .optional()
        .describe('Name for the copied file. If not provided, will use "Copy of [original name]".'),
      parentFolderId: z
        .string()
        .optional()
        .describe(
          'ID of folder where copy should be placed. If not provided, places in same location as original.'
        ),
    }),
    execute: async (args, { log }) => {
      const drive = await getDriveClient();
      log.info(`Copying file ${args.fileId} ${args.newName ? `as "${args.newName}"` : ''}`);

      try {
        // Get original file info
        const originalFile = await drive.files.get({
          fileId: args.fileId,
          fields: 'name,parents',
          supportsAllDrives: true,
        });

        const copyMetadata: drive_v3.Schema$File = {
          name: args.newName || `Copy of ${originalFile.data.name}`,
        };

        if (args.parentFolderId) {
          copyMetadata.parents = [args.parentFolderId];
        } else if (originalFile.data.parents) {
          copyMetadata.parents = originalFile.data.parents;
        }

        const response = await drive.files.copy({
          fileId: args.fileId,
          requestBody: copyMetadata,
          fields: 'id,name,webViewLink',
          supportsAllDrives: true,
        });

        const copiedFile = response.data;
        return JSON.stringify(
          {
            id: copiedFile.id,
            name: copiedFile.name,
            url: copiedFile.webViewLink,
          },
          null,
          2
        );
      } catch (error: any) {
        log.error(`Error copying file: ${error.message || error}`);
        if (error.code === 404)
          throw new UserError('Original file or destination folder not found. Check the IDs.');
        if (error.code === 403)
          throw new UserError(
            'Permission denied. Make sure you have read access to the original file and write access to the destination.'
          );
        throw new UserError(`Failed to copy file: ${error.message || 'Unknown error'}`);
      }
    },
  });
}