Skip to main content
Glama

WebSee MCP Server

by 1AQuantum
network-tracer.js7.84 kB
/** * Network Tracer Agent * Intercepts network requests and captures stack traces for source intelligence * Part of the WebSee Source Intelligence Layer */ export class NetworkTracer { traces = new Map(); /** * Initialize the network tracer with a Playwright page */ async initialize(page) { // Inject network interception script into the page await page.addInitScript(() => { // Store original functions const originalFetch = window.fetch; const originalXHROpen = XMLHttpRequest.prototype.open; const originalXHRSend = XMLHttpRequest.prototype.send; // Helper to capture stack trace const captureStackTrace = () => { const stack = new Error().stack || ''; return stack .split('\n') .slice(2) // Remove Error line and captureStackTrace line .filter(line => !line.includes('NetworkTracer')) .map(line => line.trim()) .slice(0, 10); // Limit to 10 frames }; // Intercept fetch window.fetch = async function (...args) { const startTime = Date.now(); const stackTrace = captureStackTrace(); const url = args[0] instanceof Request ? args[0].url : String(args[0]); const method = (args[1]?.method || 'GET').toUpperCase(); // Emit custom event for tracking window.dispatchEvent(new CustomEvent('__websee_network_start', { detail: { type: 'fetch', url, method, stackTrace, timestamp: startTime, }, })); try { const response = await originalFetch.apply(this, args); const duration = Date.now() - startTime; const headers = {}; response.headers.forEach((value, key) => { headers[key] = value; }); window.dispatchEvent(new CustomEvent('__websee_network_complete', { detail: { url, status: response.status, duration, headers, }, })); return response; } catch (error) { window.dispatchEvent(new CustomEvent('__websee_network_error', { detail: { url, error: String(error) }, })); throw error; } }; // Intercept XMLHttpRequest XMLHttpRequest.prototype.open = function (method, url, async, username, password) { this.__websee_url = url; this.__websee_method = method; this.__websee_stack = captureStackTrace(); return originalXHROpen.call(this, method, url, async !== undefined ? async : true, username, password); }; XMLHttpRequest.prototype.send = function (...args) { const startTime = Date.now(); window.dispatchEvent(new CustomEvent('__websee_network_start', { detail: { type: 'xhr', url: this.__websee_url, method: this.__websee_method, stackTrace: this.__websee_stack, timestamp: startTime, }, })); this.addEventListener('loadend', () => { const duration = Date.now() - startTime; window.dispatchEvent(new CustomEvent('__websee_network_complete', { detail: { url: this.__websee_url, status: this.status, duration, }, })); }); return originalXHRSend.apply(this, args); }; }); // Listen for network events await page.exposeFunction('__websee_network_handler', (event) => { this.handleNetworkEvent(event); }); await page.addInitScript(() => { ['__websee_network_start', '__websee_network_complete', '__websee_network_error'].forEach(eventName => { window.addEventListener(eventName, (e) => { window.__websee_network_handler(e.detail); }); }); }); } /** * Handle network events from the page */ handleNetworkEvent(event) { if (!event.url) return; const key = `${event.method}_${event.url}_${event.timestamp}`; if (event.stackTrace) { // Start of request this.traces.set(key, { url: event.url, method: event.method, timestamp: event.timestamp, stackTrace: event.stackTrace, initiator: { type: event.type, // Parse stack trace for source location ...this.parseStackLocation(event.stackTrace[0]), }, }); } else if (event.status !== undefined) { // Completion of request const trace = Array.from(this.traces.values()).find(t => t.url === event.url && !t.status); if (trace) { trace.status = event.status; trace.duration = event.duration; if (event.headers) { trace.responseHeaders = event.headers; } } } } /** * Parse stack trace line to extract source location */ parseStackLocation(stackLine) { const match = stackLine.match(/at .* \(?(.*):(\d+):(\d+)\)?$/); if (match) { return { url: match[1], lineNumber: parseInt(match[2]), columnNumber: parseInt(match[3]), }; } return {}; } /** * Get all network traces */ getTraces() { return Array.from(this.traces.values()); } /** * Get traces for a specific URL pattern */ getTracesForUrl(urlPattern) { const pattern = typeof urlPattern === 'string' ? new RegExp(urlPattern.replace(/\*/g, '.*')) : urlPattern; return this.getTraces().filter(trace => pattern.test(trace.url)); } /** * Clear all traces */ clearTraces() { this.traces.clear(); } /** * Get a summary of network activity */ getSummary() { const traces = this.getTraces(); const byMethod = {}; const byStatus = {}; let totalDuration = 0; let completedCount = 0; traces.forEach(trace => { byMethod[trace.method] = (byMethod[trace.method] || 0) + 1; if (trace.status) { byStatus[trace.status] = (byStatus[trace.status] || 0) + 1; } if (trace.duration) { totalDuration += trace.duration; completedCount++; } }); return { totalRequests: traces.length, byMethod, byStatus, averageDuration: completedCount > 0 ? totalDuration / completedCount : 0, }; } /** * Cleanup and destroy the tracer */ async destroy() { this.traces.clear(); } } //# sourceMappingURL=network-tracer.js.map

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/1AQuantum/websee-mcp-server'

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