metrx_set_budget
Create or update budget configurations to enforce spending limits with configurable enforcement modes for agents or entire organizations.
Instructions
Create or update a budget configuration for an agent or the entire organization. Budgets enforce spending limits with configurable enforcement modes: "alert_only" (notify but don't block), "soft_block" (block with override), or "hard_block" (strict enforcement). Specify limits in dollars. Do NOT use just to change enforcement mode — use update_budget_mode for that.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | No | Agent to set budget for. Omit for org-wide budget. | |
| period | Yes | Budget period | |
| limit_dollars | Yes | Spending limit in dollars (e.g., 100 for $100/month) | |
| warning_pct | No | Percentage of limit that triggers a warning (default: 80) | |
| enforcement_mode | No | How to enforce the budget when exceeded | alert_only |
Implementation Reference
- src/tools/budgets.ts:51-127 (handler)The set_budget tool registration and handler implementation. This is the core logic that creates or updates budget configurations. It handles the conversion from dollars to microcents, constructs the API request body, and returns formatted success/error messages.
// ── set_budget ── server.registerTool( 'set_budget', { title: 'Set Budget', description: 'Create or update a budget configuration for an agent or the entire organization. ' + 'Budgets enforce spending limits with configurable enforcement modes: ' + '"alert_only" (notify but don\'t block), "soft_block" (block with override), ' + 'or "hard_block" (strict enforcement). Specify limits in dollars. ' + 'Do NOT use just to change enforcement mode — use update_budget_mode for that.', inputSchema: { agent_id: z .string() .uuid() .optional() .describe('Agent to set budget for. Omit for org-wide budget.'), period: z.enum(['daily', 'monthly']).describe('Budget period'), limit_dollars: z .number() .positive() .describe('Spending limit in dollars (e.g., 100 for $100/month)'), warning_pct: z .number() .int() .min(1) .max(99) .default(80) .describe('Percentage of limit that triggers a warning (default: 80)'), enforcement_mode: z .enum(['alert_only', 'soft_block', 'hard_block']) .default('alert_only') .describe('How to enforce the budget when exceeded'), }, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }, async ({ agent_id, period, limit_dollars, warning_pct, enforcement_mode }) => { // Convert dollars to microcents (1 dollar = 100_000_000 microcents) const limit_microcents = Math.round(limit_dollars * 100_000_000); const body: Record<string, unknown> = { period, limit_microcents, warning_pct: warning_pct ?? 80, enforcement_mode: enforcement_mode ?? 'alert_only', }; if (agent_id) body.agent_id = agent_id; const result = await client.post<BudgetConfig>('/budgets', body); if (result.error) { return { content: [{ type: 'text', text: `Error setting budget: ${result.error}` }], isError: true, }; } const b = result.data!; const scope = b.agent_id ? `agent ${b.agent_id}` : 'organization'; return { content: [ { type: 'text', text: `✅ Budget set for ${scope}: ${formatMicrocents(b.limit_microcents)}/${ b.period } with ${b.enforcement_mode} enforcement. Warning at ${b.warning_pct}%.`, }, ], }; } ); - src/index.ts:74-103 (registration)The wrapper that adds the 'metrx_' prefix to all tool registrations. This is where 'set_budget' becomes 'metrx_set_budget'. Also includes rate limiting middleware and handler wrapping.
// ── Rate limiting middleware + metrx_ namespace prefix ── // All tools are registered exclusively as metrx_{name}. // The metrx_ prefix namespaces our tools to avoid collisions when // multiple MCP servers are used together. const METRX_PREFIX = 'metrx_'; const originalRegisterTool = server.registerTool.bind(server); (server as any).registerTool = function ( name: string, config: any, handler: (...handlerArgs: any[]) => Promise<any> ) { const wrappedHandler = async (...handlerArgs: any[]) => { if (!rateLimiter.isAllowed(name)) { return { content: [ { type: 'text' as const, text: `Rate limit exceeded for tool '${name}'. Maximum 60 requests per minute allowed.`, }, ], isError: true, }; } return handler(...handlerArgs); }; // Register with metrx_ prefix (only — no deprecated aliases) const prefixedName = name.startsWith(METRX_PREFIX) ? name : `${METRX_PREFIX}${name}`; originalRegisterTool(prefixedName, config, wrappedHandler); }; - src/types.ts:111-119 (schema)The BudgetConfig interface defining the structure of budget configuration objects returned from the API, including id, period, limit_microcents, warning_pct, enforcement_mode, paused, and agent_id fields.
export interface BudgetConfig { id: string; period: 'daily' | 'monthly'; limit_microcents: number; warning_pct: number; enforcement_mode: 'alert_only' | 'soft_block' | 'hard_block'; paused: boolean; agent_id: string | null; } - src/tools/budgets.ts:62-84 (schema)The input schema validation using Zod for the set_budget tool parameters: agent_id (optional UUID), period (enum: daily/monthly), limit_dollars (positive number), warning_pct (1-99, default 80), and enforcement_mode (enum: alert_only/soft_block/hard_block, default alert_only).
inputSchema: { agent_id: z .string() .uuid() .optional() .describe('Agent to set budget for. Omit for org-wide budget.'), period: z.enum(['daily', 'monthly']).describe('Budget period'), limit_dollars: z .number() .positive() .describe('Spending limit in dollars (e.g., 100 for $100/month)'), warning_pct: z .number() .int() .min(1) .max(99) .default(80) .describe('Percentage of limit that triggers a warning (default: 80)'), enforcement_mode: z .enum(['alert_only', 'soft_block', 'hard_block']) .default('alert_only') .describe('How to enforce the budget when exceeded'), }, - src/services/formatters.ts:26-28 (helper)The formatMicrocents helper function used by the set_budget handler to convert microcents to dollar strings for user-friendly output formatting.
export function formatMicrocents(microcents: number): string { return `$${(microcents / 100_000_000).toFixed(2)}`; }