Skip to main content
Glama
abs222222
by abs222222

download_file

Download files from web URLs with automatic browser fallback for JavaScript-heavy sites. Supports redirect handling, custom file naming, and cross-platform compatibility.

Instructions

Download a file from URL (supports redirects and browser download)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesURL to download
filenameNoSave as filename (optional). Can be absolute path.
use_browserNoForce browser download method (for JavaScript-heavy sites). Default: false

Implementation Reference

  • The main handler function that orchestrates file download using HTTP (with redirects) or browser (Playwright) methods based on parameters.
    async function downloadFile(url, filePath, useBrowser = false) {
      if (useBrowser) {
        console.error('Using browser download method...');
        return await browserDownload(url, filePath);
      }
      
      // Try HTTP download first
      try {
        console.error('Trying HTTP download with redirect support...');
        return await httpDownload(url, filePath);
      } catch (httpError) {
        console.error(`HTTP download failed: ${httpError.message}`);
        
        // If HTTP fails with too many redirects or other issues, try browser
        if (httpError.message.includes('Too many redirects') || 
            httpError.message.includes('HTTP 4') ||
            httpError.message.includes('HTTP 5')) {
          console.error('Falling back to browser download...');
          try {
            return await browserDownload(url, filePath);
          } catch (browserError) {
            // If both fail, return the original HTTP error
            throw new Error(`HTTP failed: ${httpError.message}, Browser failed: ${browserError.message}`);
          }
        }
        
        throw httpError;
      }
    }
  • Input schema definition for the download_file tool, specifying parameters url (required), filename (optional), and use_browser (optional boolean).
    {
      name: 'download_file',
      description: 'Download a file from URL (supports redirects and browser download)',
      inputSchema: {
        type: 'object',
        properties: {
          url: { 
            type: 'string', 
            description: 'URL to download' 
          },
          filename: { 
            type: 'string', 
            description: 'Save as filename (optional). Can be absolute path.' 
          },
          use_browser: {
            type: 'boolean',
            description: 'Force browser download method (for JavaScript-heavy sites). Default: false',
            default: false
          }
        },
        required: ['url']
      }
    }
  • Registers the download_file tool by handling ListToolsRequestSchema and returning the tool list containing it.
    server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: 'download_file',
            description: 'Download a file from URL (supports redirects and browser download)',
            inputSchema: {
              type: 'object',
              properties: {
                url: { 
                  type: 'string', 
                  description: 'URL to download' 
                },
                filename: { 
                  type: 'string', 
                  description: 'Save as filename (optional). Can be absolute path.' 
                },
                use_browser: {
                  type: 'boolean',
                  description: 'Force browser download method (for JavaScript-heavy sites). Default: false',
                  default: false
                }
              },
              required: ['url']
            }
          }
        ]
      };
    });
  • MCP CallToolRequestSchema handler that dispatches to downloadFile when name is 'download_file', handles file path resolution, and formats response.
      if (request.params.name === 'download_file') {
        const { url, filename, use_browser } = request.params.arguments;
        
        try {
          let filePath;
          
          if (filename && path.isAbsolute(filename)) {
            // If filename is an absolute path, use it directly
            filePath = filename;
            // Create the directory if it doesn't exist
            const dir = path.dirname(filePath);
            await fs.mkdir(dir, { recursive: true });
          } else {
            // Use the default download directory
            const downloadDir = path.join(os.homedir(), 'Downloads', 'mcp-downloads');
            await fs.mkdir(downloadDir, { recursive: true });
            
            let fname = filename;
            if (!fname) {
              try {
                const urlPath = new URL(url).pathname;
                fname = path.basename(urlPath) || 'download';
              } catch {
                fname = 'download';
              }
            }
            
            filePath = path.join(downloadDir, fname);
          }
          
          const result = await downloadFile(url, filePath, use_browser);
          
          return {
            content: [
              {
                type: 'text',
                text: `✅ Downloaded successfully!
    URL: ${url}
    Method: ${result.method}
    Saved to: ${filePath}
    Size: ${result.size} bytes`
              }
            ]
          };
        } catch (error) {
          return {
            content: [
              {
                type: 'text',
                text: `❌ Download failed!
    URL: ${url}
    Error: ${error.message}`
              }
            ]
          };
        }
      }
  • Helper function for HTTP-based file download supporting redirects.
    async function httpDownload(url, filePath, redirectCount = 0) {
      const maxRedirects = 10;
      
      return new Promise((resolve, reject) => {
        if (redirectCount > maxRedirects) {
          reject(new Error(`Too many redirects (>${maxRedirects})`));
          return;
        }
        
        const client = url.startsWith('https') ? https : http;
        
        client.get(url, {
          headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
          }
        }, (response) => {
          // Handle redirects (301, 302, 303, 307, 308)
          if ([301, 302, 303, 307, 308].includes(response.statusCode)) {
            const redirectUrl = response.headers.location;
            if (!redirectUrl) {
              reject(new Error(`Redirect ${response.statusCode} but no location header`));
              return;
            }
            
            // Handle relative redirects
            let newUrl = redirectUrl;
            if (!redirectUrl.startsWith('http')) {
              const baseUrl = new URL(url);
              newUrl = new URL(redirectUrl, baseUrl).toString();
            }
            
            console.error(`Following redirect: ${url} -> ${newUrl}`);
            
            // Recursively follow the redirect
            httpDownload(newUrl, filePath, redirectCount + 1)
              .then(resolve)
              .catch(reject);
            return;
          }
          
          // Check for success
          if (response.statusCode !== 200) {
            reject(new Error(`HTTP ${response.statusCode}`));
            return;
          }
          
          // Download the file
          const file = createWriteStream(filePath);
          let size = 0;
          
          response.on('data', (chunk) => {
            size += chunk.length;
          });
          
          response.pipe(file);
          
          file.on('finish', () => {
            file.close();
            resolve({ size, method: 'http' });
          });
          
          file.on('error', (err) => {
            file.close();
            fs.unlink(filePath).catch(() => {});
            reject(err);
          });
          
        }).on('error', (err) => {
          reject(err);
        });
      });
    }
Install Server

Other Tools

Latest Blog Posts

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/abs222222/mcp-file-downloader'

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