Skip to main content
Glama
dennisonbertram

Brex MCP Server

spendLimits.ts4.17 kB
/** * @file Spend Limits Resource Handler * @description Implements resource handlers for Brex spend limits API endpoints */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { logDebug, logError } from '../utils/logger.js'; import { ResourceTemplate } from '../models/resourceTemplate.js'; import { BrexClient } from '../services/brex/client.js'; import { parseQueryParams } from '../models/common.js'; import { isSpendLimit } from '../models/budget.js'; import { estimateTokens } from '../utils/responseLimiter.js'; /** * Get Brex client */ function getBrexClient(): BrexClient { return new BrexClient(); } /** * Resource template for spend limits API */ const spendLimitsTemplate = new ResourceTemplate('brex://spend_limits{/id}'); /** * Register the spend limits resource handler * @param server - MCP server instance */ export const registerSpendLimitsResource = (server: Server): void => { server.setRequestHandler(ReadResourceRequestSchema, async (request: unknown) => { const req = request as { params: { uri: string } }; const { uri } = req.params; if (!canHandleSpendLimitsUri(uri)) return { handled: false } as any; return await readSpendLimitsUri(uri); }); }; export function registerSpendLimitsCapabilities(server: Server): void { server.registerCapabilities({ resources: { "brex://spend_limits{/id}": { description: "Brex spend limits (list or by ID)", mimeTypes: ["application/json"], } } }); } export function canHandleSpendLimitsUri(uri: string): boolean { return uri.startsWith('brex://spend_limits'); } export async function readSpendLimitsUri(uri: string): Promise<any> { logDebug(`Handling spend limit request for URI: ${uri}`); const brexClient = getBrexClient(); const params = spendLimitsTemplate.parse(uri); const id = params.id; if (id) { const spendLimit = await brexClient.getSpendLimit(id); if (!spendLimit || !isSpendLimit(spendLimit)) throw new Error(`Invalid spend limit data received for ID: ${id}`); const qp = parseQueryParams(uri); const fields = qp.fields ? qp.fields.split(',').map(s => s.trim()).filter(Boolean) : undefined; const summaryOnly = qp.summary_only === 'true'; const summarized = summaryOnly || estimateTokens(JSON.stringify(spendLimit)) > 24000; const out = fields && fields.length ? project(spendLimit, fields) : spendLimit; return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(summarized ? out : spendLimit, null, 2) }] } as any; } else { const queryParams = parseQueryParams(uri); const spendLimitsResponse = await brexClient.getSpendLimits({ cursor: queryParams.cursor, limit: queryParams.limit ? parseInt(queryParams.limit, 10) : undefined, parent_budget_id: queryParams.parent_budget_id, status: queryParams.status as any, member_user_id: queryParams.member_user_id }); const qp = parseQueryParams(uri); const fields = qp.fields ? qp.fields.split(',').map(s => s.trim()).filter(Boolean) : undefined; const summaryOnly = qp.summary_only === 'true'; const summarized = summaryOnly || estimateTokens(JSON.stringify(spendLimitsResponse)) > 24000; const projected = fields && fields.length ? spendLimitsResponse.items.map((b: any) => project(b, fields)) : spendLimitsResponse.items; const out = summarized ? { ...spendLimitsResponse, items: projected } : spendLimitsResponse; return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(out, null, 2) }] } as any; } } function project(src: any, fields?: string[]): any { if (!fields || !fields.length) return src; const out: any = {}; for (const f of fields) { const parts = f.split('.'); let cur: any = src; for (const p of parts) { cur = cur?.[p]; if (cur === undefined) break; } if (cur !== undefined) { let o: any = out; for (let i = 0; i < parts.length - 1; i++) { o[parts[i]] = o[parts[i]] ?? {}; o = o[parts[i]]; } o[parts[parts.length - 1]] = cur; } } return out; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dennisonbertram/mcp-brex'

If you have feedback or need assistance with the MCP directory API, please join our Discord server