Skip to main content
Glama

Dropbox MCP Server

dbx-operations.test.ts9.04 kB
import { describe, it, expect, beforeAll, afterAll } from '@jest/globals'; import fs from 'node:fs'; import path from 'node:path'; import { spawn } from 'node:child_process'; import { decryptData, encryptData } from '../src/security-utils.js'; import dotenv from 'dotenv'; import { setupTestLogger, restoreConsole } from './utils/test-logger.js'; import { testResultsTracker } from './utils/test-results-tracker.js'; // Load environment variables dotenv.config(); // Get root directory const rootDir = process.cwd(); // Configuration const SERVER_COMMAND = 'node'; const SERVER_ARGS = [path.join(rootDir, 'build', 'src', 'index.js')]; const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const TEST_FOLDER_NAME = `mcp-test-${timestamp}`; const TEST_FILE_NAME = `test-file-${timestamp}.txt`; const TEST_FILE_CONTENT = 'Hello, this is a test file created by the Dropbox MCP test suite.'; const TOKEN_STORE_PATH = path.join(rootDir, '.tokens.json'); // Helper functions function encodeBase64(text: string): string { return Buffer.from(text).toString('base64'); } function decodeBase64(base64: string): string { return Buffer.from(base64, 'base64').toString('utf-8'); } async function sendMcpRequest(request: any): Promise<any> { return new Promise((resolve, reject) => { const serverProcess = spawn(SERVER_COMMAND, SERVER_ARGS, { stdio: ['pipe', 'pipe', 'pipe'], env: { ...process.env } }); let responseData = ''; let errorData = ''; serverProcess.stdout.on('data', (data) => { responseData += data.toString(); }); serverProcess.stderr.on('data', (data) => { errorData += data.toString(); }); serverProcess.on('close', (code) => { if (code !== 0) { reject(new Error(`Server process exited with code ${code}: ${errorData}`)); return; } try { const lines = responseData.trim().split('\n'); const lastLine = lines[lines.length - 1]; const response = JSON.parse(lastLine); resolve(response); } catch (error) { reject(error); } }); serverProcess.stdin.write(JSON.stringify(request) + '\n'); serverProcess.stdin.end(); }); } async function callMcpTool(toolName: string, args: any = {}): Promise<any> { const request = { jsonrpc: '2.0', id: Date.now().toString(), method: 'tools/call', params: { name: toolName, arguments: args } }; const response = await sendMcpRequest(request); if (response.error) { throw new Error(`MCP error: ${JSON.stringify(response.error)}`); } return response.result; } describe('Dropbox MCP Server', () => { const FILE_NAME = 'dbx-operations.test.ts'; beforeAll(() => { // Set up the custom logger to suppress stack traces setupTestLogger(); // Reset the test results tracker testResultsTracker.reset(); // Verify token store exists if (!fs.existsSync(TOKEN_STORE_PATH)) { throw new Error('Token store not found. Please complete the authentication setup first.'); } // Verify token data const tokenData = JSON.parse(fs.readFileSync(TOKEN_STORE_PATH, 'utf-8')); const decrypted = decryptData(tokenData); if (!decrypted.accessToken || !decrypted.refreshToken) { throw new Error('Invalid token data'); } }); afterAll(async () => { // Clean up test folder try { await callMcpTool('delete_item', { path: `/${TEST_FOLDER_NAME}` }); console.log('Cleaned up test folder in Dropbox'); } catch (error) { console.error('Failed to clean up test folder:', error); } // Print test summary testResultsTracker.printSummary(timestamp, TEST_FOLDER_NAME); // Restore original console methods restoreConsole(); }); beforeEach(() => { const testName = expect.getState().currentTestName; if (testName) { testResultsTracker.registerTest(testName, FILE_NAME); } }); afterEach(() => { const testName = expect.getState().currentTestName; if (testName) { const isPassed = !expect.getState().currentTestName?.includes('failed'); if (isPassed) { testResultsTracker.markTestPassed(testName, FILE_NAME); } } }); it('should get account information', async () => { const response = await callMcpTool('get_account_info'); const accountInfo = JSON.parse(response.content[0].text); expect(accountInfo.account_id).toBeDefined(); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { accountId: accountInfo.account_id, name: accountInfo.name?.display_name, email: accountInfo.email, accountType: accountInfo.account_type }); }); it('should create a folder', async () => { const response = await callMcpTool('create_folder', { path: `/${TEST_FOLDER_NAME}` }); expect(response).toBeDefined(); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { folderName: TEST_FOLDER_NAME, path: `/${TEST_FOLDER_NAME}` }); }); it('should upload a file', async () => { const encodedContent = encodeBase64(TEST_FILE_CONTENT); const response = await callMcpTool('upload_file', { path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}`, content: encodedContent }); expect(response).toBeDefined(); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { fileName: TEST_FILE_NAME, path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}`, contentSize: TEST_FILE_CONTENT.length }); }); it('should get file metadata', async () => { const response = await callMcpTool('get_file_metadata', { path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}` }); const metadata = JSON.parse(response.content[0].text); expect(metadata.name).toBe(TEST_FILE_NAME); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { name: metadata.name, path: metadata.path_display, size: metadata.size, modified: metadata.server_modified }); }); it('should download a file', async () => { const response = await callMcpTool('download_file', { path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}` }); const reference = JSON.parse(response.content[0].text); const content = decodeBase64(reference.content.content); expect(content).toBe(TEST_FILE_CONTENT); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}`, contentSize: content.length, contentMatch: content === TEST_FILE_CONTENT }); }); it('should list files', async () => { const response = await callMcpTool('list_files', { path: `/${TEST_FOLDER_NAME}` }); const files = JSON.parse(response.content[0].text); expect(files).toHaveLength(1); expect(files[0].name).toBe(TEST_FILE_NAME); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { path: `/${TEST_FOLDER_NAME}`, fileCount: files.length, files: files.map((f: { name: string }) => f.name).join(', ') }); }); it('should search for files', async () => { const response = await callMcpTool('search_file_db', { query: TEST_FILE_NAME, path: '', max_results: 10 }); const results = JSON.parse(response.content[0].text); expect(results).toBeDefined(); expect(results.matches || results).toEqual( expect.arrayContaining([ expect.objectContaining({ metadata: expect.objectContaining({ name: TEST_FILE_NAME }) }) ]) ); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { query: TEST_FILE_NAME, totalResults: results.total_results, matchCount: results.matches?.length || 0 }); }); it('should handle safe delete with confirmation', async () => { const response = await callMcpTool('safe_delete_item', { path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}`, userId: 'test_user' }); const result = JSON.parse(response.content[0].text); expect(result.status).toBe('confirmation_required'); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}`, status: result.status, message: result.message }); }); it('should perform safe delete with skip confirmation', async () => { const response = await callMcpTool('safe_delete_item', { path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}`, userId: 'test_user', skipConfirmation: true }); const result = JSON.parse(response.content[0].text); expect(result.status).toBe('success'); testResultsTracker.addTestDetails(expect.getState().currentTestName!, FILE_NAME, { path: `/${TEST_FOLDER_NAME}/${TEST_FILE_NAME}`, status: result.status, operation: result.operation }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Albiemark/dbx-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server