drive_files_copy
Copy a Google Drive file and optionally convert it to a different format, like markdown to Google Doc.
Instructions
Copy a file. Useful for converting formats (e.g. markdown to Google Doc).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| fileId | Yes | Source file ID to copy | |
| fields | No | Fields to return | |
| name | Yes | Name for the copy | |
| mimeType | No | Target MIME type for conversion | |
| parents | No | Parent folder IDs (JSON array as string) |
Implementation Reference
- src/services.ts:78-91 (schema)Tool definition for 'drive_files_copy' — declares the MCP tool name, description, gws CLI command (drive files copy), and input parameters/schema (fileId, fields as query params; name, mimeType, parents as body params). Default params include supportsAllDrives:true.
{ name: "drive_files_copy", description: "Copy a file. Useful for converting formats (e.g. markdown to Google Doc).", command: ["drive", "files", "copy"], params: [ { name: "fileId", description: "Source file ID to copy", type: "string", required: true }, { name: "fields", description: "Fields to return", type: "string", required: false }, ], bodyParams: [ { name: "name", description: "Name for the copy", type: "string", required: true }, { name: "mimeType", description: "Target MIME type for conversion", type: "string", required: false }, { name: "parents", description: "Parent folder IDs (JSON array as string)", type: "string", required: false }, ], defaultParams: DRIVE_SHARED_DEFAULTS_NO_INCLUDE, - src/index.ts:156-179 (registration)Generic tool registration loop — 'drive_files_copy' is registered here via the server.tool() call. The loop iterates over all ToolDefs (including drive_files_copy), builds a Zod schema from its definition, and registers a handler that calls executeGws() to run the underlying gws CLI command.
// Register each tool for (const tool of tools) { const schema = buildZodSchema(tool); server.tool( tool.name, tool.description, schema, async (args) => { const result = await executeGws(tool, args as Record<string, unknown>, gwsBinary); if (result.success) { return { content: [{ type: "text" as const, text: result.output || "(empty response)" }], }; } else { return { content: [{ type: "text" as const, text: `Error: ${result.error}` }], isError: true, }; } }, ); } - src/index.ts:101-132 (helper)buildZodSchema — dynamically creates a Zod validation schema for each tool (including drive_files_copy). Converts param/bodyParam definitions into Zod types (string, number, boolean) with optional/required flags.
export function buildZodSchema(tool: ToolDef): Record<string, z.ZodTypeAny> { const shape: Record<string, z.ZodTypeAny> = {}; const allParams = [...tool.params, ...(tool.bodyParams || [])]; for (const p of allParams) { let field: z.ZodTypeAny; switch (p.type) { case "number": field = z.number().describe(p.description); break; case "boolean": field = z.boolean().describe(p.description); break; default: field = z.string().describe(p.description); } if (!p.required) { field = field.optional(); } shape[p.name] = field; } // Add optional uploadPath for tools that support file upload if (tool.supportsUpload) { shape.uploadPath = z.string().describe("Local file path to upload").optional(); } return shape; } - src/executor.ts:181-210 (handler)executeGws — the actual execution handler that runs the tool. For drive_files_copy, it calls buildArgs() to construct the CLI command (gws drive files copy --params ... --json ...) and spawns the gws CLI process. This is the shared handler invoked when the drive_files_copy tool is called.
export async function executeGws( tool: ToolDef, args: Record<string, unknown>, gwsBinary: string, ): Promise<ExecResult> { const cliArgs = buildArgs(tool, args); console.error(`[gws-mcp] Executing: ${gwsBinary} ${cliArgs.join(" ")}`); try { const { stdout, stderr } = await spawnGwsRaw(gwsBinary, cliArgs); if (stderr) { console.error(`[gws-mcp] stderr: ${stderr}`); } return { success: true, output: stdout || "(empty response)" }; } catch (err: unknown) { const error = err as { message?: string }; let message = error.message || "Unknown error"; // Enhance Drive 404 errors with actionable hints if (message.includes("404") && message.includes("not found") && tool.command[0] === "drive") { message += "\n\nHint: If this file is in a shared drive, ensure supportsAllDrives is set (this should be automatic). Check that the file ID is correct and the authenticated account has access."; } console.error(`[gws-mcp] Error: ${message}`); return { success: false, output: "", error: message }; } } - src/executor.ts:76-129 (helper)buildArgs — constructs the CLI arguments for the gws command. For drive_files_copy, it builds --params from fileId/fields and --json from name/mimeType/parents, plus default params (supportsAllDrives).
export function buildArgs( tool: ToolDef, args: Record<string, unknown>, ): string[] { const cliArgs = [...tool.command]; // Collect --params (query/path parameters) // Start with defaults (e.g. supportsAllDrives), then overlay caller values const params: Record<string, unknown> = { ...(tool.defaultParams || {}) }; for (const p of tool.params) { if (args[p.name] !== undefined) { params[p.name] = args[p.name]; } } if (Object.keys(params).length > 0) { cliArgs.push("--params", escapeJsonArg(JSON.stringify(params))); } // Collect --json (request body) if (tool.bodyParams && tool.bodyParams.length > 0) { const body: Record<string, unknown> = {}; for (const p of tool.bodyParams) { if (args[p.name] !== undefined) { let val = args[p.name]; if (typeof val === "string") { try { const parsed = JSON.parse(val); if (typeof parsed === "object") { val = parsed; } } catch { // Keep as string } } body[p.name] = val; } } if (Object.keys(body).length > 0) { cliArgs.push("--json", escapeJsonArg(JSON.stringify(body))); } } // File upload — validate path before passing to CLI if (tool.supportsUpload && args.uploadPath) { const safePath = sanitizeUploadPath(String(args.uploadPath)); if (process.platform === "win32") { cliArgs.push("--upload", escapeForCmd(safePath)); } else { cliArgs.push("--upload", safePath); } } return cliArgs; }