npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mcp-fe/event-tracker

v0.0.16

Published

Framework-agnostic event tracking library for the MCP-FE (Model Context Protocol - Frontend Edge) ecosystem. This library provides a simple, clean API for tracking user interactions and making them available to AI agents through the MCP protocol.

Readme

@mcp-fe/event-tracker

Framework-agnostic event tracking library for the MCP-FE (Model Context Protocol - Frontend Edge) ecosystem. This library provides a simple, clean API for tracking user interactions and making them available to AI agents through the MCP protocol.

Overview

@mcp-fe/event-tracker is a lightweight wrapper around @mcp-fe/mcp-worker that provides an ergonomic API for tracking user events in any JavaScript application. It serves as the foundation for framework-specific integrations like @mcp-fe/react-event-tracker.

Key Features

  • Framework Agnostic: Works with any JavaScript framework or vanilla JS
  • Simple API: Clean, intuitive functions for common tracking needs
  • Rich Event Data: Captures element details, metadata, and context
  • Connection Management: Built-in WebSocket connection status monitoring
  • Authentication Support: Token-based authentication for user-specific events
  • TypeScript Support: Full type definitions included

Installation

npm install @mcp-fe/event-tracker
# or
pnpm add @mcp-fe/event-tracker
# or
yarn add @mcp-fe/event-tracker

Dependencies

This package requires @mcp-fe/mcp-worker which is automatically installed as a dependency. Make sure to set up the worker files as described in the mcp-worker documentation.

Quick Start

import { 
  initEventTracker, 
  trackEvent, 
  trackNavigation, 
  trackClick 
} from '@mcp-fe/event-tracker';

// Initialize the event tracker
await initEventTracker({
  backendWsUrl: 'ws://localhost:3001'
});

// Track user interactions
await trackNavigation('/home', '/products');
await trackClick(document.getElementById('buy-button'));

// Track custom events
await trackEvent({
  type: 'custom',
  metadata: {
    eventName: 'purchase_completed',
    orderId: '12345',
    amount: 99.99
  }
});

API Reference

Initialization

initEventTracker(options?)

Initialize the event tracking system. This sets up the underlying MCP worker.

Parameters:

  • options?: ServiceWorkerRegistration | WorkerClientInitOptions

WorkerClientInitOptions:

interface WorkerClientInitOptions {
  sharedWorkerUrl?: string;    // Default: '/mcp-shared-worker.js'
  serviceWorkerUrl?: string;   // Default: '/mcp-service-worker.js'
  backendWsUrl?: string;       // Default: 'ws://localhost:3001'
}

Examples:

// Basic initialization
await initEventTracker();

// With custom WebSocket URL
await initEventTracker({
  backendWsUrl: 'wss://my-mcp-server.com/ws'
});

// With custom worker paths
await initEventTracker({
  sharedWorkerUrl: '/assets/workers/mcp-shared-worker.js',
  backendWsUrl: 'ws://localhost:3001'
});

// Using existing ServiceWorker registration
const registration = await navigator.serviceWorker.register('/mcp-service-worker.js');
await initEventTracker(registration);

Event Tracking

trackEvent(eventData)

Track a generic user event with custom data.

Parameters:

  • eventData: UserEventData

UserEventData Interface:

interface UserEventData {
  type: 'navigation' | 'click' | 'input' | 'custom';
  path?: string;           // Current page path
  from?: string;           // Previous location (navigation events)
  to?: string;             // Next location (navigation events)
  element?: string;        // HTML element tag name
  elementId?: string;      // Element ID attribute
  elementClass?: string;   // Element CSS classes
  elementText?: string;    // Element text content (truncated to 100 chars)
  metadata?: Record<string, unknown>; // Additional event data
}

Example:

await trackEvent({
  type: 'custom',
  path: '/dashboard',
  metadata: {
    eventName: 'feature_used',
    feature: 'export_data',
    format: 'csv',
    recordCount: 150
  }
});

trackNavigation(from, to, path?)

Track navigation between routes or pages.

Parameters:

  • from: string - Previous route/URL
  • to: string - Current route/URL
  • path?: string - Optional explicit path (defaults to to)

Example:

// Basic navigation tracking
await trackNavigation('/home', '/products');

// With explicit path
await trackNavigation('/users/123', '/users/456', '/users');

trackClick(element, path?, metadata?)

Track click events on HTML elements with automatic element data extraction.

Parameters:

  • element: HTMLElement - The clicked element
  • path?: string - Current page path (defaults to window.location.pathname)
  • metadata?: Record<string, unknown> - Additional click data

Example:

// Track button click
const button = document.getElementById('submit-btn');
await trackClick(button);

// With additional metadata
const link = document.querySelector('a[data-product-id="123"]');
await trackClick(link, '/products', {
  productId: '123',
  category: 'electronics',
  price: 299.99
});

// Event listener example
document.addEventListener('click', async (event) => {
  if (event.target instanceof HTMLElement) {
    await trackClick(event.target);
  }
});

trackInput(element, value?, path?)

Track input changes in forms with debouncing and value length tracking.

Parameters:

  • element: HTMLElement - The input element
  • value?: string - Input value (stored securely with length tracking)
  • path?: string - Current page path

Example:

// Track input change
const emailInput = document.getElementById('email');
await trackInput(emailInput, emailInput.value);

// Event listener with debouncing
let timeoutId;
document.addEventListener('input', (event) => {
  if (event.target instanceof HTMLInputElement) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(async () => {
      await trackInput(event.target, event.target.value);
    }, 1000); // 1 second debounce
  }
});

trackCustom(eventName, metadata?, path?)

Convenient wrapper for tracking custom business events.

Parameters:

  • eventName: string - Name of the custom event
  • metadata?: Record<string, unknown> - Event-specific data
  • path?: string - Current page path

Example:

// Track business events
await trackCustom('purchase_completed', {
  orderId: '12345',
  amount: 99.99,
  currency: 'USD',
  items: ['product-1', 'product-2']
});

await trackCustom('search_performed', {
  query: 'javascript tutorials',
  results: 42,
  filters: ['beginner', 'video']
});

await trackCustom('error_occurred', {
  errorType: 'validation',
  field: 'email',
  message: 'Invalid email format'
});

Connection Management

getConnectionStatus()

Check if the MCP worker is connected to the proxy server.

Returns: Promise<boolean>

Example:

const isConnected = await getConnectionStatus();
if (!isConnected) {
  console.warn('MCP connection lost, events may not be available to AI agents');
}

onConnectionStatus(callback) / offConnectionStatus(callback)

Subscribe to connection status changes.

Parameters:

  • callback: (connected: boolean) => void - Status change callback

Example:

const handleConnectionChange = (connected) => {
  console.log('MCP connection:', connected ? 'Connected' : 'Disconnected');
  
  // Update UI indicator
  const indicator = document.getElementById('connection-status');
  indicator.className = connected ? 'connected' : 'disconnected';
  indicator.textContent = connected ? '🟢 Connected' : '🔴 Offline';
};

// Start listening
onConnectionStatus(handleConnectionChange);

// Stop listening (e.g., on component unmount)
offConnectionStatus(handleConnectionChange);

Authentication

setAuthToken(token)

Set authentication token for associating events with specific users.

Parameters:

  • token: string - Authentication token (e.g., JWT)

Example:

// After user login
async function handleLogin(credentials) {
  const response = await authenticateUser(credentials);
  
  // Set token for MCP tracking
  setAuthToken(response.accessToken);
  
  // Track login event
  await trackCustom('user_logged_in', {
    userId: response.user.id,
    method: 'password'
  });
}

// On logout
async function handleLogout() {
  await trackCustom('user_logged_out');
  
  // Clear authentication
  setAuthToken('');
}

Integration with AI Agents

Once events are tracked and stored, AI agents can query them through the MCP protocol:

{
  "jsonrpc": "2.0",
  "method": "tools/call", 
  "params": {
    "name": "get_user_events",
    "arguments": {
      "type": "click",
      "limit": 10,
      "startTime": 1705712400000
    }
  }
}

This enables AI agents to:

  • Provide context-aware customer support
  • Debug user interface issues
  • Analyze user behavior patterns
  • Guide users through complex workflows
  • Understand error scenarios and user frustration points

Best Practices

Event Granularity

// ✅ Good: Track meaningful interactions
await trackClick(submitButton, '/checkout', {
  step: 'payment',
  amount: totalAmount
});

// ❌ Too granular: Don't track every mouseover
document.addEventListener('mouseover', trackEvent); // Avoid this

Sensitive Data

// ✅ Good: Track input activity without sensitive values
await trackInput(passwordInput, undefined, '/login'); // Don't pass actual password

// ✅ Good: Track metadata about sensitive operations
await trackCustom('payment_submitted', {
  amount: 99.99,
  currency: 'USD',
  // Don't include card numbers or CVV
});

Performance

// ✅ Good: Debounce high-frequency events
let searchTimeout;
searchInput.addEventListener('input', () => {
  clearTimeout(searchTimeout);
  searchTimeout = setTimeout(async () => {
    await trackInput(searchInput, searchInput.value);
  }, 500);
});

// ✅ Good: Batch related events
await Promise.all([
  trackCustom('form_submitted'),
  trackNavigation('/form', '/success')
]);

Error Handling

// Wrap tracking calls in try-catch for production resilience
async function safeTrackEvent(eventData) {
  try {
    await trackEvent(eventData);
  } catch (error) {
    // Log error but don't break user experience
    console.warn('Failed to track event:', error);
  }
}

// Check connection before critical tracking
const isConnected = await getConnectionStatus();
if (isConnected) {
  await trackCustom('critical_business_event', eventData);
} else {
  // Store locally or queue for later
  localStorage.setItem('pending_events', JSON.stringify([eventData]));
}

Troubleshooting

Events Not Being Stored

  1. Check worker initialization: Ensure initEventTracker() completed successfully
  2. Verify worker files: Make sure MCP worker files are in your public directory
  3. Check connection: Use getConnectionStatus() to verify proxy connection

Connection Issues

  1. Proxy server: Verify the MCP proxy server is running at the specified WebSocket URL
  2. CORS: Check browser console for CORS errors
  3. WebSocket: Verify WebSocket connection in browser Developer Tools

Memory Usage

  1. Event cleanup: Periodically clean old events from IndexedDB
  2. Debouncing: Use appropriate debouncing for high-frequency events
  3. Selective tracking: Only track events that provide value to AI agents

Requirements

  • Modern Browser: ES2020+ support
  • MCP Worker Setup: Requires @mcp-fe/mcp-worker configuration
  • MCP Proxy Server: A running MCP proxy server to collect events

Related Packages

Credits

Created and maintained with ❤️ by Michal Kopecký.

License

Licensed under the Apache License, Version 2.0. See the LICENSE file for details.