JSPM

@auvh/climeter-mcp

0.1.0
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 7
    • Score
      100M100P100Q48713F
    • License MIT

    Usage-based billing for MCP servers — wrap any MCP tool with CLIMeter metering

    Package Exports

    • @auvh/climeter-mcp

    Readme

    @auvh/climeter-mcp

    Usage-based billing for MCP servers — wrap any MCP tool with CLIMeter metering in one line.

    npm version License: MIT

    What is this?

    @auvh/climeter-mcp is a companion to @auvh/climeter that makes it trivial to add usage-based billing to any MCP (Model Context Protocol) server.

    Before:

    server.tool('search', SearchSchema, async (params) => {
      return doSearch(params.query)
    })

    After — metered:

    import { mcpTool } from '@auvh/climeter-mcp'
    
    server.tool('search', SearchSchema, mcpTool('search', async (params) => {
      return doSearch(params.query)
    }))

    Every call is tracked: invocation count, execution time, success/error status. Pricing is configured in the CLIMeter dashboard.


    Installation

    npm install @auvh/climeter @auvh/climeter-mcp

    Quick Start

    1. Wrap a single tool — mcpTool()

    Best for one-off billing on specific tools.

    import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
    import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
    import { z } from 'zod'
    import { meter } from '@auvh/climeter'
    import { mcpTool } from '@auvh/climeter-mcp'
    
    meter.configure({
      apiKey: process.env.CLIMETER_API_KEY,
      toolSlug: 'my-server',
    })
    
    const server = new McpServer({ name: 'my-server', version: '1.0.0' })
    
    server.tool(
      'search',
      { query: z.string() },
      mcpTool('search', async ({ query }) => {
        const results = await doSearch(query)
        return { content: [{ type: 'text', text: results }] }
      })
    )
    
    await server.connect(new StdioServerTransport())

    2. Wrap all tools at once — mcpServer()

    Register tools normally, then wrap everything in one call.

    import { mcpServer } from '@auvh/climeter-mcp'
    
    const server = new McpServer({ name: 'my-server', version: '1.0.0' })
    
    server.tool('search', SearchSchema, searchHandler)
    server.tool('summarize', SumSchema, summarizeHandler)
    server.tool('ping', {}, pingHandler)
    
    // Wrap all tools — ping is free (won't be billed)
    mcpServer(server, {
      toolSlug: 'my-server',
      free: ['ping'],
    })
    
    await server.connect(transport)

    3. HTTP middleware — withMeter()

    For MCP servers running over HTTP/SSE (Express, Hono, Fastify).

    import express from 'express'
    import { withMeter } from '@auvh/climeter-mcp'
    
    const app = express()
    app.use(express.json())
    
    // Apply withMeter before your MCP HTTP handler
    app.use('/mcp', withMeter({ toolSlug: 'my-server' }), mcpHttpHandler)
    
    app.listen(3000)

    API Reference

    mcpTool(name, handler, options?)

    Wraps a single MCP tool handler with CLIMeter billing.

    Parameter Type Description
    name string Tool name (used as billing event name)
    handler (params: T) => Promise<R> Original tool handler
    options McpMeterOptions Optional configuration

    McpMeterOptions:

    Option Type Default Description
    billingName string name Override event name for billing
    metadata Record<string, unknown> {} Extra metadata attached to every event
    free boolean false Skip billing entirely for this tool

    mcpServer(server, options?)

    Wraps ALL registered tools on an MCP McpServer instance. Call after registering all tools, before server.connect().

    Parameter Type Description
    server McpServer The MCP server instance
    options McpServerOptions Optional configuration

    McpServerOptions:

    Option Type Description
    toolSlug string Slug attached to all billing events
    free string[] Tool names to skip billing for

    withMeter(options?)

    Express/Connect middleware for HTTP MCP servers. Intercepts tools/call requests and tracks billing after the response.

    Parameter Type Description
    options WithMeterOptions Optional configuration

    WithMeterOptions:

    Option Type Description
    toolSlug string Slug attached to all billing events

    guardBalance(toolSlug, minBalance?)

    Pre-flight balance check. Throws if balance is below threshold. Use on the consumer side.

    await guardBalance('my-server', 0.01) // throws if balance < $0.01

    withBalanceGuard(toolSlug, fn, minBalance?)

    Wraps a function with balance guard — checks before executing.

    const search = withBalanceGuard('my-server', async (params) => {
      return mcpClient.callTool('search', params)
    })
    
    // Throws InsufficientBalanceError if balance is too low
    const result = await search({ query: 'hello' })

    Claude Desktop Configuration

    Add your metered MCP server to claude_desktop_config.json:

    {
      "mcpServers": {
        "my-server": {
          "command": "node",
          "args": ["/path/to/my-server/dist/index.js"],
          "env": {
            "CLIMETER_API_KEY": "clim_v1_..."
          }
        }
      }
    }

    Events Tracked

    Every metered call records:

    Field Description
    event Tool name (or billingName override)
    duration_ms Execution time in milliseconds
    status "success" or "error"
    transport "mcp" (stdio) or "http"
    tool_slug Your tool slug (if provided)

    Pricing

    Pricing per call is configured in the CLIMeter dashboard — not in the SDK. This ensures billing integrity and lets you change pricing without redeploying.



    License

    MIT