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 🙏

© 2025 – Pkg Stats / Ryan Hefner

agnost

v0.1.7

Published

Analytics SDK for Model Context Protocol Servers

Readme

Agnost Analytics SDK (TypeScript)

npm version License: MIT

Analytics SDK for tracking and analyzing Model Context Protocol (MCP) server interactions.

Installation

npm install agnost

Setup Example

import { trackMCP, createConfig } from 'agnost';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';

// Create your MCP server instance
const server = new Server(
  {
    name: "my-server",
    version: "1.0.0"
  },
  {
    capabilities: {
      tools: {}
    }
  }
);

// Configure analytics
const config = createConfig({
  endpoint: "https://api.agnost.ai",
  disableInput: false,
  disableOutput: false
});

// Enable analytics tracking
const trackedServer = trackMCP(server, "your-organization-id", config);

Configuration Example

import { trackMCP, createConfig } from 'agnost';

// Create a custom configuration
const config = createConfig({
  endpoint: "https://api.agnost.ai",
  disableInput: false,   // Set to true to disable input tracking
  disableOutput: false   // Set to true to disable output tracking
});

// Apply the configuration
trackMCP(
  server,
  "your-organization-id",
  config
);

User Identification

The SDK supports user identification to track analytics per user. This is especially useful for understanding usage patterns across different users and roles.

Basic User Identification

import { trackMCP, createConfig } from 'agnost';

// Enable user identification
trackMCP(server, 'your-org-id', {
  // .. other config like disableInput, disableOutput
  identify: (request, env) => ({
    userId: request?.headers?.['x-user-id'] || env?.USER_ID || 'anonymous',
    email: request?.headers?.['x-user-email'] || env?.USER_EMAIL,
    role: request?.headers?.['x-user-role'] || env?.USER_ROLE || 'user'
  })
});

Advanced User Identification

import { trackMCP, createConfig } from 'agnost';

// Complex identification logic with async operations
trackMCP(server, 'your-org-id', {
  identify: async (request, env) => {
    try {
      // Extract token from headers
      const token = request?.headers?.['authorization']?.replace('Bearer ', '');
      if (!token) {
        return { userId: 'anonymous' };
      }

      // You could validate token and fetch user info
      // const userInfo = await validateTokenAndGetUser(token);

      // Return user identity with custom fields
      return {
        userId: 'user-123',
        email: '[email protected]',
        role: 'admin',
        organization: 'acme-corp',
        subscription: 'premium'
      };
    } catch (error) {
      console.warn('User identification failed:', error);
      return { userId: 'anonymous' };
    }
  }
});

User Identity Interface

The identify function should return a UserIdentity object or null:

interface UserIdentity {
  userId: string;        // Required: Unique user identifier
  [key: string]: any;   // Optional: Any additional user properties
}

type IdentifyFunction = (
  request?: any,                              // MCP request object with headers, params, etc.
  env?: Record<string, string | undefined>    // Environment variables (process.env)
) => UserIdentity | null | Promise<UserIdentity | null>;

Identify Function Parameters

  • request: The incoming MCP request object containing:

    • headers: HTTP-style headers (e.g., x-user-id, authorization)
    • params: Request parameters including tool name and arguments
    • Other request metadata from the MCP protocol
  • env: Environment variables from process.env, useful for:

    • Reading user info from environment variables
    • Accessing configuration secrets
    • Getting deployment-specific user context

Common Usage Patterns

1. Header-based Identification

identify: (request, env) => ({
  userId: request?.headers?.['x-user-id'] || 'anonymous',
  role: request?.headers?.['x-user-role'] || 'user'
})

2. Environment Variable Identification

identify: (request, env) => ({
  userId: env?.USER_ID || env?.LOGGED_IN_USER || 'anonymous',
  workspace: env?.WORKSPACE_ID
})

3. Token-based Identification

identify: async (request, env) => {
  const authHeader = request?.headers?.['authorization'];
  if (authHeader?.startsWith('Bearer ')) {
    const token = authHeader.replace('Bearer ', '');
    const decoded = await decodeJWT(token);
    return {
      userId: decoded.sub,
      email: decoded.email,
      role: decoded.role
    };
  }
  return { userId: 'anonymous' };
}

Important Notes

  • The userId field is required in the returned UserIdentity object
  • If identification fails, return null or { userId: 'anonymous' }
  • User identification happens once per session and is cached
  • Any errors in the identify function are logged and fallback to anonymous tracking
  • Additional fields beyond userId are included in analytics for segmentation

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | endpoint | string | "https://api.agnost.ai" | API endpoint URL | | disableInput | boolean | false | Disable tracking of input arguments | | disableOutput | boolean | false | Disable tracking of output results | | identify | IdentifyFunction | undefined | Function to identify users from request context |