Skip to main content
Glama

js.analyze

Analyze JavaScript files to extract endpoints and secrets for security testing and vulnerability assessment.

Instructions

Download, beautify, and analyze a JavaScript file - extract endpoints and secrets

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesURL of the JS file to analyze

Implementation Reference

  • Handler function for 'js.analyze' tool: Downloads JS from URL using axios, beautifies with js-beautify, extracts endpoints (URLs and paths) using regex, extracts API keys using regex patterns, stores analysis in Redis via setWorkingMemory, returns formatted result with summary.
    async ({ url }: any): Promise<ToolResult> => { try { // Download let source: string; try { const response = await axios.get(url, { timeout: 30000, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', }, }); source = response.data; } catch (error: any) { return formatToolResult(false, null, `Failed to download: ${error.message}`); } // Beautify let beautified: string; try { beautified = beautify.js(source, { indent_size: 2, space_in_empty_paren: true, preserve_newlines: true, }); } catch { beautified = source; } // Find endpoints const urlRegex = /\bhttps?:\/\/[\w\-\.:%]+[\w\-\/_\.\?\=\%\&\#]*/g; const urls = Array.from(new Set(beautified.match(urlRegex) || [])); const pathRegex = /["'`](\/[-a-zA-Z0-9_@:\/\.]+)["'`]/g; const paths: string[] = []; let match: RegExpExecArray | null; while ((match = pathRegex.exec(beautified)) !== null) { paths.push(match[1]); } const endpoints = { urls, paths: Array.from(new Set(paths)), }; // Extract secrets (simplified) const secrets: any = { apiKeys: [], tokens: [], candidates: [], }; const apiKeyPattern = /(?:api[_-]?key|apikey)[\s:=]+["'`]([A-Za-z0-9_\-]{20,})["'`]/gi; let keyMatch: RegExpExecArray | null; while ((keyMatch = apiKeyPattern.exec(beautified)) !== null) { secrets.apiKeys.push(keyMatch[1]); } secrets.apiKeys = Array.from(new Set(secrets.apiKeys)); await setWorkingMemory(`js:analysis:${url}`, { endpoints, secrets, }, 7200); return formatToolResult(true, { url, endpoints, secrets, summary: { endpointsFound: (endpoints.urls?.length || 0) + (endpoints.paths?.length || 0), secretsFound: (secrets.apiKeys?.length || 0) + (secrets.tokens?.length || 0), }, }); } catch (error: any) { return formatToolResult(false, null, error.message); } }
  • Input schema and description for the 'js.analyze' tool: requires a single 'url' string parameter.
    description: 'Download, beautify, and analyze a JavaScript file - extract endpoints and secrets', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'URL of the JS file to analyze' }, }, required: ['url'], }, },
  • Registers the 'js.analyze' tool within the registerJsTools function using server.tool(name, schema, handler). This function is called from src/index.ts.
    server.tool( 'js.analyze', { description: 'Download, beautify, and analyze a JavaScript file - extract endpoints and secrets', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'URL of the JS file to analyze' }, }, required: ['url'], }, }, async ({ url }: any): Promise<ToolResult> => { try { // Download let source: string; try { const response = await axios.get(url, { timeout: 30000, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', }, }); source = response.data; } catch (error: any) { return formatToolResult(false, null, `Failed to download: ${error.message}`); } // Beautify let beautified: string; try { beautified = beautify.js(source, { indent_size: 2, space_in_empty_paren: true, preserve_newlines: true, }); } catch { beautified = source; } // Find endpoints const urlRegex = /\bhttps?:\/\/[\w\-\.:%]+[\w\-\/_\.\?\=\%\&\#]*/g; const urls = Array.from(new Set(beautified.match(urlRegex) || [])); const pathRegex = /["'`](\/[-a-zA-Z0-9_@:\/\.]+)["'`]/g; const paths: string[] = []; let match: RegExpExecArray | null; while ((match = pathRegex.exec(beautified)) !== null) { paths.push(match[1]); } const endpoints = { urls, paths: Array.from(new Set(paths)), }; // Extract secrets (simplified) const secrets: any = { apiKeys: [], tokens: [], candidates: [], }; const apiKeyPattern = /(?:api[_-]?key|apikey)[\s:=]+["'`]([A-Za-z0-9_\-]{20,})["'`]/gi; let keyMatch: RegExpExecArray | null; while ((keyMatch = apiKeyPattern.exec(beautified)) !== null) { secrets.apiKeys.push(keyMatch[1]); } secrets.apiKeys = Array.from(new Set(secrets.apiKeys)); await setWorkingMemory(`js:analysis:${url}`, { endpoints, secrets, }, 7200); return formatToolResult(true, { url, endpoints, secrets, summary: { endpointsFound: (endpoints.urls?.length || 0) + (endpoints.paths?.length || 0), secretsFound: (secrets.apiKeys?.length || 0) + (secrets.tokens?.length || 0), }, }); } catch (error: any) { return formatToolResult(false, null, error.message); } } );
  • src/index.ts:36-36 (registration)
    Top-level call to registerJsTools(server) in the main server initialization, which registers js.analyze and other JS tools.
    registerJsTools(server);

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/telmon95/VulneraMCP'

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