UNPKG

dbx-mcp-server

Version:

A Model Context Protocol server for Dropbox integration with AI-powered PDF analysis, multi-directory indexing, and parallel processing

230 lines 8.2 kB
import { getDropboxClientForPath, formatDropboxPath } from './client-factory.js'; import { handleDropboxError } from './error-handler.js'; export async function listFiles(path) { try { const client = await getDropboxClientForPath(path); const response = await client.filesListFolder({ path: formatDropboxPath(path), recursive: false, include_media_info: true, include_deleted: false, include_has_explicit_shared_members: false, include_mounted_folders: true, include_non_downloadable_files: true }); // Convert entries to a simpler format for listing const files = response.result.entries.map(entry => ({ '.tag': entry['.tag'], name: entry.name, path_display: entry.path_display, size: entry['.tag'] === 'file' ? entry.size : 0, server_modified: entry['.tag'] === 'file' ? entry.server_modified : null, client_modified: entry['.tag'] === 'file' ? entry.client_modified : null })); return { content: [{ type: 'text', text: JSON.stringify(files, null, 2) }], }; } catch (error) { handleDropboxError(error); } } export async function uploadFile(path, content) { try { const buffer = Buffer.from(content, 'base64'); const client = await getDropboxClientForPath(path); await client.filesUpload({ path: formatDropboxPath(path), contents: buffer, mode: { '.tag': 'overwrite' }, }); return { content: [{ type: 'text', text: `File uploaded successfully to ${path}`, }], }; } catch (error) { handleDropboxError(error); } } export async function downloadFile(path) { try { const client = await getDropboxClientForPath(path); // Get metadata first to check if it's a file or folder const metadata = await client.filesGetMetadata({ path: formatDropboxPath(path) }); if (metadata.result['.tag'] === 'folder') { // For folders, get contents and format as ResourceContent const folderContents = await client.filesListFolder({ path: formatDropboxPath(path), recursive: false, include_media_info: true, include_deleted: false, include_has_explicit_shared_members: false, include_mounted_folders: true, include_non_downloadable_files: true }); // For folders, return a list of ResourceReference objects const files = folderContents.result.entries.map(entry => ({ uri: `dbx://${entry.path_display?.slice(1) || entry.name}`, name: entry.name, description: entry['.tag'] === 'file' ? `File (${entry.size} bytes)` : 'Folder' })); return { content: [{ type: 'text', text: JSON.stringify({ uri: `dbx://${path.replace(/^\//, '')}`, name: metadata.result.name, description: `Folder containing ${files.length} items`, mimeType: 'application/vnd.dropbox.folder', items: files }, null, 2) }], }; } else { // For files, download and return content const fileResponse = await client.filesDownload({ path: formatDropboxPath(path) }); const fileData = fileResponse.result; // Create downloads directory if it doesn't exist const fs = await import('fs'); const downloadDir = 'downloads'; if (!fs.existsSync(downloadDir)) { fs.mkdirSync(downloadDir, { recursive: true }); } // Save to downloads directory with timestamp const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const fileName = `${timestamp}_${metadata.result.name}`; const filePath = `${downloadDir}/${fileName}`; fs.writeFileSync(filePath, fileData.fileBinary); return { content: [{ type: 'text', text: `File downloaded successfully to: ${filePath}`, }], }; } } catch (error) { handleDropboxError(error); } } export async function createFolder(path) { try { const client = await getDropboxClientForPath(path); await client.filesCreateFolderV2({ path: formatDropboxPath(path), autorename: false, }); return { content: [{ type: 'text', text: `Created folder at ${path}`, }], }; } catch (error) { handleDropboxError(error); } } export async function getFileMetadata(path) { try { const client = await getDropboxClientForPath(path); const response = await client.filesGetMetadata({ path: formatDropboxPath(path), include_media_info: true, include_deleted: false, include_has_explicit_shared_members: true, }); return { content: [{ type: 'text', text: JSON.stringify(response.result, null, 2), }], }; } catch (error) { handleDropboxError(error); } } export async function getFileContent(path) { try { const client = await getDropboxClientForPath(path); // Get metadata first to verify it's a file const metadata = await client.filesGetMetadata({ path: formatDropboxPath(path) }); if (metadata.result['.tag'] !== 'file') { return { content: [{ type: 'text', text: `Error: ${path} is not a file`, }], }; } // Download the file content const fileResponse = await client.filesDownload({ path: formatDropboxPath(path) }); const fileData = fileResponse.result; // Convert to base64 for safe transport const content = Buffer.from(fileData.fileBinary).toString('base64'); return { content: [{ type: 'text', text: JSON.stringify({ name: metadata.result.name, size: metadata.result.size, content: content, encoding: 'base64' }, null, 2), }], }; } catch (error) { handleDropboxError(error); } } // Get raw file metadata for processing (used by PDF analyzer and indexer) export async function getRawFileMetadata(path) { try { const client = await getDropboxClientForPath(path); const response = await client.filesGetMetadata({ path: formatDropboxPath(path), include_media_info: true, include_deleted: false, include_has_explicit_shared_members: true, }); return response.result; } catch (error) { handleDropboxError(error); } } // Download file as Buffer for processing (used by PDF analyzer) export async function downloadFileAsBuffer(path) { try { const client = await getDropboxClientForPath(path); // Download the file const response = await client.filesDownload({ path: formatDropboxPath(path) }); const fileData = response.result; return fileData.fileBinary; } catch (error) { handleDropboxError(error); } } //# sourceMappingURL=file-operations.js.map