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

@metricai/node-sdk

v0.1.0

Published

MetricAI SDK for Node.js - Gemini support through the MetricAI proxy

Downloads

26

Readme

MetricAI Node.js SDK

A lightweight Node.js SDK for using Google Gemini through the MetricAI proxy, providing metering, billing, and cost tracking for AI applications.

What is MetricAI?

MetricAI is an AI billing and metering proxy for India (INR/UPI). It sits between your application and LLM providers to:

  • Track usage across agents and users
  • Bill accurately with usage-based, outcome-based, or hybrid modes
  • Set budget caps to prevent runaway costs
  • Provide dashboards for monitoring spend

Features

  • 🚀 Simple API — Drop-in replacement for @google/generative-ai
  • 💰 Metering & Billing — Automatic cost tracking per agent/user/session
  • 🎯 Attribution — Track which agent and user made each request
  • 💳 Budget Caps — Set INR limits per request or globally
  • 🧾 Billing Modes — Usage, outcome, or hybrid billing
  • 🔑 BYOK Support — Bring your own Gemini keys
  • 📊 Dashboard Integration — View costs in real-time
  • 🔒 TypeScript — Full type safety with IntelliSense
  • 🌊 Streaming — Support for streaming responses

Installation

npm install @metricai/node-sdk

Peer Dependency Required:

The SDK wraps @google/generative-ai, which you must install separately:

npm install @google/generative-ai

Quick Start

1. Get Your API Key

Sign up at metricai.co.in and get your API key (starts with mk_live_ or mk_test_).

2. Basic Usage

import { MetricAI } from '@metricai/node-sdk';

// Initialize the client
const client = new MetricAI({ apiKey: 'mk_live_your_api_key' });

// Get a Gemini model through the MetricAI proxy
const model = client.gemini().getGenerativeModel({
  model: 'gemini-2.0-flash',
});

// Make API calls
const result = await model.generateContent('Hello, world!');
console.log(result.response.text());

That's it! Your request is now routed through MetricAI and being metered.


Usage Patterns

With Attribution (Track Agents & Users)

const client = new MetricAI({
  apiKey: 'mk_live_your_api_key',
  agentId: 'my-chatbot',      // Which agent/service
  userId: 'user-12345',       // Which end user
  billingMode: 'hybrid',       // How to bill
  budgetCapInr: 100,          // Cap at ₹100 per day
});

// All requests will be attributed to this agent/user
const model = client.gemini().getGenerativeModel({
  model: 'gemini-2.0-flash',
});

const result = await model.generateContent('Summarize this document...');

Per-Request Overrides

Override attribution settings for specific requests:

const model = client.gemini({
  agentId: 'priority-agent',
  budgetCapInr: 500,
}).getGenerativeModel({
  model: 'gemini-2.0-flash',
});

const result = await model.generateContent('Complex task requiring higher budget...');

Multiple Agents

Create separate client instances for different parts of your application:

const chatbotClient = new MetricAI({
  apiKey: process.env.METRICAI_API_KEY,
  agentId: 'chatbot-agent',
});

const summarizerClient = new MetricAI({
  apiKey: process.env.METRICAI_API_KEY,
  agentId: 'summarizer-agent',
});

// Chatbot request
const chatModel = chatbotClient.gemini().getGenerativeModel({ model: 'gemini-2.0-flash' });
const chatResult = await chatModel.generateContent('Hello!');

// Summarizer request
const summaryModel = summarizerClient.gemini().getGenerativeModel({ model: 'gemini-pro' });
const summaryResult = await summaryModel.generateContent('Summarize this text...');

Bring Your Own Keys (BYOK)

If you have your own Gemini API key, use BYOK mode:

const client = new MetricAI({
  apiKey: 'mk_live_metricai_key',       // MetricAI key for auth
  geminiApiKey: 'your_gemini_api_key',  // Your Gemini key for billing
});

Generation Configuration

Pass standard Gemini generation config:

const model = client.gemini().getGenerativeModel({
  model: 'gemini-2.0-flash',
  generationConfig: {
    temperature: 0.7,
    maxOutputTokens: 2048,
    topP: 0.9,
    topK: 40,
  },
});

const result = await model.generateContent({
  contents: [{
    role: 'user',
    parts: [{ text: 'Explain quantum computing in simple terms.' }],
  }],
});

System Instructions

const model = client.gemini().getGenerativeModel({
  model: 'gemini-2.0-flash',
  systemInstruction: {
    parts: [{
      text: 'You are a helpful coding assistant. Always explain your reasoning.',
    }],
  },
});

const result = await model.generateContent('How do I sort an array?');

Multi-Turn Conversations

const chat = client.gemini().startChat({
  history: [
    { role: 'user', parts: [{ text: 'What is Node.js?' }] },
    { role: 'model', parts: [{ text: 'Node.js is a JavaScript runtime...' }] },
  ],
});

const response = await chat.sendMessage('And what is npm?');
console.log(response.response.text());

const response2 = await chat.sendMessage('Thanks!');
console.log(response2.response.text());

Streaming Responses

const model = client.gemini().getGenerativeModel({
  model: 'gemini-2.0-flash',
});

const streamingResult = await model.generateContentStream('Write a story about a robot.');

for await (const chunk of streamingResult.stream) {
  const text = chunk.text();
  process.stdout.write(text);
}
console.log('\n');

Raw Headers (Manual HTTP)

If you're not using the SDK directly, you can still use MetricAI headers:

import { buildHeaders, mergeHeaders } from '@metricai/node-sdk';

// Build headers for manual fetch/axios calls
const headers = buildHeaders({
  apiKey: 'mk_live_your_api_key',
  agentId: 'my-agent',
  userId: 'user-123',
  billingMode: 'hybrid',
  budgetCapInr: 50,
});

// Use with fetch
const response = await fetch(
  'https://proxy.metricai.co.in/v1/proxy/gemini/v1beta/models/gemini-2.0-flash:generateContent',
  {
    method: 'POST',
    headers: {
      ...headers,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      contents: [{ parts: [{ text: 'Hello!' }] }],
    }),
  }
);

const data = await response.json();
console.log(data.candidates?.[0]?.content?.parts?.[0]?.text);

Configuration

MetricAIOptions

| Option | Type | Default | Description | |--------|------|---------|-------------| | apiKey | string | required | Your MetricAI API key | | baseUrl | string | Production proxy | Custom proxy URL (for self-hosted) | | geminiApiKey | string | MetricAI key | Your Gemini API key (BYOK mode) | | agentId | string | 'default-agent' | Default agent identifier | | userId | string | 'anonymous' | Default user identifier | | sessionId | string | auto-generated | Conversation session ID (UUID) | | billingMode | BillingMode | 'hybrid' | Billing mode | | budgetCapInr | number | undefined | Default budget cap in INR | | environment | Environment | 'production' | 'production' or 'sandbox' |

Billing Modes

| Mode | Description | |------|-------------| | usage | Pay per token used (input + output) | | outcome | Pay on successful outcome (e.g., booking confirmed) | | hybrid | Combination of usage + outcome charges |

Environment Modes

| Mode | Description | |------|-------------| | production | Routes to live MetricAI proxy | | sandbox | Routes to sandbox/testing environment |


Environment Variables

The SDK automatically reads these environment variables:

| Variable | Description | |----------|-------------| | METRICAI_API_KEY | Your MetricAI API key |


Error Handling

import { MetricAI } from '@metricai/node-sdk';

const client = new MetricAI({ apiKey: 'mk_live_your_api_key' });
const model = client.gemini().getGenerativeModel({ model: 'gemini-2.0-flash' });

try {
  const result = await model.generateContent('Hello!');
  console.log(result.response.text());
} catch (error: any) {
  if (error.response) {
    // API returned an error
    console.error('API Error:', error.response.status, error.response.data);
  } else if (error.code === 'ECONNREFUSED') {
    // Proxy unreachable (fail-open: request may still go through)
    console.error('Could not connect to MetricAI proxy');
  } else {
    // Other error
    console.error('Error:', error.message);
  }
}

TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

import { MetricAI, MetricAIOptions, BillingMode } from '@metricai/node-sdk';

const options: MetricAIOptions = {
  apiKey: 'mk_live_your_api_key',
  agentId: 'my-agent',
  userId: 'user-123',
  billingMode: 'hybrid' as BillingMode,
  budgetCapInr: 100,
};

const client = new MetricAI(options);

Common Issues

"MetricAI API key is required"

Make sure you've provided a valid API key:

const client = new MetricAI({ apiKey: 'mk_live_your_key' });

Requests are not appearing in dashboard

Check that your agentId and userId are being set correctly. Each unique agentId + userId combination creates a separate cost center in the dashboard.

Budget exceeded errors

If you're hitting budget caps, increase the budgetCapInr value or set it to undefined to remove the cap:

const client = new MetricAI({
  apiKey: 'mk_live_your_key',
  budgetCapInr: undefined, // No budget cap
});

SDK Architecture

┌─────────────────┐     ┌─────────────────┐     ┌──────────────┐
│  Your App       │────▶│  MetricAI SDK   │────▶│  MetricAI   │
│  (Node.js)      │     │  (adds headers) │     │  Proxy      │
└─────────────────┘     └─────────────────┘     └──────────────┘
                                                        │
                                                        ▼
                                                 ┌──────────────┐
                                                 │  Google      │
                                                 │  Gemini API  │
                                                 └──────────────┘

Testing

# Run unit tests
npm test

# Run tests in watch mode
npm run test:watch

# Type check
npm run lint

# Build
npm run build

License

MIT