import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import type { PulseApiClient } from "../client.js";
import { formatResult } from "../format.js";
export function registerMeteringTools(server: McpServer, client: PulseApiClient) {
server.tool(
"track_event",
"Track a single usage event for a customer",
{
meterId: z.string().describe("The meter ID to track against"),
customerId: z.string().describe("The customer's external ID"),
value: z.string().describe("The usage value (e.g. '1', '1500')"),
timestamp: z.string().optional().describe("ISO 8601 timestamp (defaults to now)"),
metadata: z
.record(z.unknown())
.optional()
.describe("Optional metadata key-value pairs"),
},
async (params) => {
const result = await client.post("/api/v1/metering/events", params);
return { content: [{ type: "text", text: formatResult(result) }] };
}
);
server.tool(
"track_events_batch",
"Track multiple usage events in a single request",
{
events: z
.array(
z.object({
meterId: z.string(),
customerId: z.string(),
value: z.string(),
timestamp: z.string().optional(),
metadata: z.record(z.unknown()).optional(),
})
)
.describe("Array of events to track"),
},
async ({ events }) => {
const result = await client.post("/api/v1/metering/events/batch", {
events,
});
return { content: [{ type: "text", text: formatResult(result) }] };
}
);
server.tool(
"get_usage",
"Query aggregated usage data, optionally filtered by product, customer, or date range",
{
productId: z.string().optional().describe("Filter by product ID"),
customerId: z.string().optional().describe("Filter by customer external ID"),
startDate: z.string().optional().describe("Start date (ISO 8601)"),
endDate: z.string().optional().describe("End date (ISO 8601)"),
},
async (params) => {
const result = await client.get("/api/v1/metering/usage", {
productId: params.productId,
customerId: params.customerId,
startDate: params.startDate,
endDate: params.endDate,
});
return { content: [{ type: "text", text: formatResult(result) }] };
}
);
}