mcp-gdrive-enhanced-markov
Version:
MCP server for Google Drive and Sheets with write capabilities, AI-powered PDF analysis, SQLite document indexing, and advanced directory exploration tools
139 lines (138 loc) • 6.09 kB
JavaScript
import { z } from 'zod';
import { google } from 'googleapis';
import { getValidCredentials } from '../auth.js';
export const name = 'gdrive_list_folder_contents';
export const description = 'List all files and folders contained within a specific Google Drive folder by ID';
export const inputSchema = z.object({
folderId: z.string().describe('The Google Drive folder ID to list contents from'),
includeFiles: z.boolean().optional().default(true).describe('Include files in the listing'),
includeFolders: z.boolean().optional().default(true).describe('Include folders in the listing'),
orderBy: z.enum(['name', 'modifiedTime', 'createdTime', 'size']).optional().default('name').describe('Sort order for results'),
pageSize: z.number().min(1).max(1000).optional().default(100).describe('Number of items to return (1-1000)'),
showDetails: z.boolean().optional().default(false).describe('Show detailed file information including size, modified date, etc.')
});
export const schema = {
name,
description,
inputSchema: {
type: 'object',
properties: {
folderId: { type: 'string', description: 'The Google Drive folder ID to list contents from' },
includeFiles: { type: 'boolean', description: 'Include files in the listing', default: true },
includeFolders: { type: 'boolean', description: 'Include folders in the listing', default: true },
orderBy: {
type: 'string',
enum: ['name', 'modifiedTime', 'createdTime', 'size'],
description: 'Sort order for results',
default: 'name'
},
pageSize: { type: 'number', description: 'Number of items to return (1-1000)', default: 100, minimum: 1, maximum: 1000 },
showDetails: { type: 'boolean', description: 'Show detailed file information', default: false }
},
required: ['folderId']
}
};
export async function gdrive_list_folder_contents(args) {
try {
const authClient = await getValidCredentials();
const drive = google.drive({ version: 'v3', auth: authClient });
// First verify the folder exists and is actually a folder
try {
const folderInfo = await drive.files.get({
fileId: args.folderId,
fields: 'id,name,mimeType'
});
if (folderInfo.data.mimeType !== 'application/vnd.google-apps.folder') {
return {
content: [{
type: 'text',
text: `Error: ${args.folderId} is not a folder (type: ${folderInfo.data.mimeType})`
}],
isError: true
};
}
}
catch (error) {
return {
content: [{
type: 'text',
text: `Error: Folder ${args.folderId} not found or not accessible`
}],
isError: true
};
}
// Build the query
let query = `'${args.folderId}' in parents and trashed=false`;
if (!args.includeFiles && args.includeFolders) {
query += " and mimeType='application/vnd.google-apps.folder'";
}
else if (args.includeFiles && !args.includeFolders) {
query += " and mimeType!='application/vnd.google-apps.folder'";
}
const fields = args.showDetails
? 'files(id,name,mimeType,size,modifiedTime,createdTime,parents,webViewLink)'
: 'files(id,name,mimeType,parents,webViewLink)';
// Get the files
const response = await drive.files.list({
q: query,
orderBy: args.orderBy,
pageSize: args.pageSize,
fields: fields
});
const files = response.data.files || [];
if (files.length === 0) {
return {
content: [{
type: 'text',
text: 'No files or folders found in this directory.'
}],
isError: false
};
}
// Format the output
const output = [`Found ${files.length} item(s) in folder:\n`];
files.forEach((file, index) => {
const isFolder = file.mimeType === 'application/vnd.google-apps.folder';
const icon = isFolder ? '📁' : '📄';
output.push(`${index + 1}. ${icon} ${file.name}`);
output.push(` ID: ${file.id}`);
output.push(` Type: ${isFolder ? 'Folder' : file.mimeType}`);
if (args.showDetails) {
if (file.size && !isFolder) {
const sizeKB = Math.round(parseInt(file.size) / 1024);
output.push(` Size: ${sizeKB.toLocaleString()} KB`);
}
if (file.modifiedTime) {
output.push(` Modified: ${new Date(file.modifiedTime).toLocaleDateString()}`);
}
if (file.createdTime) {
output.push(` Created: ${new Date(file.createdTime).toLocaleDateString()}`);
}
}
if (file.webViewLink) {
output.push(` URL: ${file.webViewLink}`);
}
output.push('');
});
// Add summary
const folderCount = files.filter(f => f.mimeType === 'application/vnd.google-apps.folder').length;
const fileCount = files.length - folderCount;
output.push(`Summary: ${folderCount} folder(s), ${fileCount} file(s)`);
return {
content: [{
type: 'text',
text: output.join('\n')
}],
isError: false
};
}
catch (error) {
return {
content: [{
type: 'text',
text: `Error listing folder contents: ${error instanceof Error ? error.message : 'Unknown error'}`
}],
isError: true
};
}
}