{"_id":"@auvh/climeter-mcp","name":"@auvh/climeter-mcp","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@auvh/climeter-mcp","type":"module","version":"0.1.0","description":"Usage-based billing for MCP servers — wrap any MCP tool with CLIMeter metering","main":"./dist/cjs/index.js","module":"./dist/esm/index.js","types":"./dist/types/index.d.ts","exports":{".":{"require":"./dist/cjs/index.js","import":"./dist/esm/index.js","types":"./dist/types/index.d.ts"}},"scripts":{"build":"tsc -p tsconfig.json && tsc -p tsconfig.cjs.json","test":"node --import tsx/esm --test tests/*.test.ts"},"keywords":["mcp","billing","metering","model-context-protocol","climeter","usage-based"],"license":"MIT","peerDependencies":{"@auvh/climeter":">=0.1.6"},"devDependencies":{"@auvh/climeter":"^0.1.6","@modelcontextprotocol/sdk":"^1.0.0","tsx":"^4.21.0","typescript":"^5.0.0"},"_id":"@auvh/climeter-mcp@0.1.0","gitHead":"4bbe63b1c960b0a00c64fdc61fe5d81c2ba7144d","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-uTJNgF1p/mFYFa3rFrtnW6SjTusu90GFIESH2OHsyooa7t5I6Prnfgfe9hz/fl4cIYQ21dyhdcB4X879t/1hvQ==","shasum":"a8f32c7a6a34d289141955a5c112a04a26551758","tarball":"https://registry.npmjs.org/@auvh/climeter-mcp/-/climeter-mcp-0.1.0.tgz","fileCount":33,"unpackedSize":35064,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGSkvpO7z/N1+XivLhAAp6JoirF3YuF0H1ggWVzcRB4uAiBepRXWftjkB4qekv9X8l4ZPeg2/1MgwwCOqoGE+O2Cqg=="}]},"_npmUser":{"name":"auvh","email":"agent@auvh.ai"},"directories":{},"maintainers":[{"name":"auvh","email":"agent@auvh.ai"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/climeter-mcp_0.1.0_1774553180524_0.9005499058623452"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-26T19:26:20.380Z","0.1.0":"2026-03-26T19:26:20.671Z","modified":"2026-03-26T19:26:20.889Z"},"maintainers":[{"name":"auvh","email":"agent@auvh.ai"}],"description":"Usage-based billing for MCP servers — wrap any MCP tool with CLIMeter metering","keywords":["mcp","billing","metering","model-context-protocol","climeter","usage-based"],"license":"MIT","readme":"# @auvh/climeter-mcp\n\n> Usage-based billing for MCP servers — wrap any MCP tool with CLIMeter metering in one line.\n\n[![npm version](https://img.shields.io/npm/v/@auvh/climeter-mcp)](https://www.npmjs.com/package/@auvh/climeter-mcp)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## What is this?\n\n`@auvh/climeter-mcp` is a companion to [`@auvh/climeter`](https://www.npmjs.com/package/@auvh/climeter) that makes it trivial to add usage-based billing to any MCP (Model Context Protocol) server.\n\n**Before:**\n```typescript\nserver.tool('search', SearchSchema, async (params) => {\n  return doSearch(params.query)\n})\n```\n\n**After — metered:**\n```typescript\nimport { mcpTool } from '@auvh/climeter-mcp'\n\nserver.tool('search', SearchSchema, mcpTool('search', async (params) => {\n  return doSearch(params.query)\n}))\n```\n\nEvery call is tracked: invocation count, execution time, success/error status. Pricing is configured in the [CLIMeter dashboard](https://climeter.ai).\n\n---\n\n## Installation\n\n```bash\nnpm install @auvh/climeter @auvh/climeter-mcp\n```\n\n---\n\n## Quick Start\n\n### 1. Wrap a single tool — `mcpTool()`\n\nBest for one-off billing on specific tools.\n\n```typescript\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport { meter } from '@auvh/climeter'\nimport { mcpTool } from '@auvh/climeter-mcp'\n\nmeter.configure({\n  apiKey: process.env.CLIMETER_API_KEY,\n  toolSlug: 'my-server',\n})\n\nconst server = new McpServer({ name: 'my-server', version: '1.0.0' })\n\nserver.tool(\n  'search',\n  { query: z.string() },\n  mcpTool('search', async ({ query }) => {\n    const results = await doSearch(query)\n    return { content: [{ type: 'text', text: results }] }\n  })\n)\n\nawait server.connect(new StdioServerTransport())\n```\n\n### 2. Wrap all tools at once — `mcpServer()`\n\nRegister tools normally, then wrap everything in one call.\n\n```typescript\nimport { mcpServer } from '@auvh/climeter-mcp'\n\nconst server = new McpServer({ name: 'my-server', version: '1.0.0' })\n\nserver.tool('search', SearchSchema, searchHandler)\nserver.tool('summarize', SumSchema, summarizeHandler)\nserver.tool('ping', {}, pingHandler)\n\n// Wrap all tools — ping is free (won't be billed)\nmcpServer(server, {\n  toolSlug: 'my-server',\n  free: ['ping'],\n})\n\nawait server.connect(transport)\n```\n\n### 3. HTTP middleware — `withMeter()`\n\nFor MCP servers running over HTTP/SSE (Express, Hono, Fastify).\n\n```typescript\nimport express from 'express'\nimport { withMeter } from '@auvh/climeter-mcp'\n\nconst app = express()\napp.use(express.json())\n\n// Apply withMeter before your MCP HTTP handler\napp.use('/mcp', withMeter({ toolSlug: 'my-server' }), mcpHttpHandler)\n\napp.listen(3000)\n```\n\n---\n\n## API Reference\n\n### `mcpTool(name, handler, options?)`\n\nWraps a single MCP tool handler with CLIMeter billing.\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `name` | `string` | Tool name (used as billing event name) |\n| `handler` | `(params: T) => Promise<R>` | Original tool handler |\n| `options` | `McpMeterOptions` | Optional configuration |\n\n**`McpMeterOptions`:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `billingName` | `string` | `name` | Override event name for billing |\n| `metadata` | `Record<string, unknown>` | `{}` | Extra metadata attached to every event |\n| `free` | `boolean` | `false` | Skip billing entirely for this tool |\n\n---\n\n### `mcpServer(server, options?)`\n\nWraps ALL registered tools on an MCP `McpServer` instance.\nCall after registering all tools, before `server.connect()`.\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `server` | `McpServer` | The MCP server instance |\n| `options` | `McpServerOptions` | Optional configuration |\n\n**`McpServerOptions`:**\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `toolSlug` | `string` | Slug attached to all billing events |\n| `free` | `string[]` | Tool names to skip billing for |\n\n---\n\n### `withMeter(options?)`\n\nExpress/Connect middleware for HTTP MCP servers. Intercepts `tools/call` requests and tracks billing after the response.\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `options` | `WithMeterOptions` | Optional configuration |\n\n**`WithMeterOptions`:**\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `toolSlug` | `string` | Slug attached to all billing events |\n\n---\n\n### `guardBalance(toolSlug, minBalance?)`\n\nPre-flight balance check. Throws if balance is below threshold. Use on the consumer side.\n\n```typescript\nawait guardBalance('my-server', 0.01) // throws if balance < $0.01\n```\n\n---\n\n### `withBalanceGuard(toolSlug, fn, minBalance?)`\n\nWraps a function with balance guard — checks before executing.\n\n```typescript\nconst search = withBalanceGuard('my-server', async (params) => {\n  return mcpClient.callTool('search', params)\n})\n\n// Throws InsufficientBalanceError if balance is too low\nconst result = await search({ query: 'hello' })\n```\n\n---\n\n## Claude Desktop Configuration\n\nAdd your metered MCP server to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"my-server\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/my-server/dist/index.js\"],\n      \"env\": {\n        \"CLIMETER_API_KEY\": \"clim_v1_...\"\n      }\n    }\n  }\n}\n```\n\n---\n\n## Events Tracked\n\nEvery metered call records:\n\n| Field | Description |\n|-------|-------------|\n| `event` | Tool name (or `billingName` override) |\n| `duration_ms` | Execution time in milliseconds |\n| `status` | `\"success\"` or `\"error\"` |\n| `transport` | `\"mcp\"` (stdio) or `\"http\"` |\n| `tool_slug` | Your tool slug (if provided) |\n\n---\n\n## Pricing\n\nPricing per call is configured in the [CLIMeter dashboard](https://climeter.ai) — not in the SDK. This ensures billing integrity and lets you change pricing without redeploying.\n\n---\n\n## Links\n\n- 📦 [npm: @auvh/climeter](https://www.npmjs.com/package/@auvh/climeter)\n- 📦 [npm: @auvh/climeter-mcp](https://www.npmjs.com/package/@auvh/climeter-mcp)\n- 🌐 [climeter.ai](https://climeter.ai)\n- 🐙 [GitHub](https://github.com/auvhx/climeter)\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-8e575ccfe9dd8dbb71e35fcd337013fa"}