Skip to main content
Glama
index.ts21.7 kB
/** * @file Tools Index * @version 1.0.0 * @description Exports and registers all tools for the Brex MCP server */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { registerGetTransactions } from "./getTransactions.js"; import { registerGetExpenses } from "./getExpenses.js"; import { registerGetAccountDetails } from "./getAccountDetails.js"; import { registerUploadReceipt } from "./uploadReceipt.js"; import { registerMatchReceipt } from "./matchReceipt.js"; import { registerUpdateExpense } from "./updateExpense.js"; import { registerGetAllAccounts } from "./getAllAccounts.js"; import { registerGetAllExpenses } from "./getAllExpenses.js"; import { registerGetAllCardExpenses } from "./getAllCardExpenses.js"; import { registerGetCardTransactions } from "./getCardTransactions.js"; import { registerGetCashAccountStatements } from "./getCashAccountStatements.js"; import { registerGetExpenseById } from "./getExpenseById.js"; import { registerGetCardExpenseById } from "./getCardExpenseById.js"; import { registerGetCardStatementsPrimary } from "./getCardStatementsPrimary.js"; import { registerGetCashTransactions } from "./getCashTransactions.js"; import { registerGetBudgets } from "./getBudgets.js"; import { registerGetBudgetById } from "./getBudgetById.js"; import { registerGetSpendLimits } from "./getSpendLimits.js"; import { registerGetSpendLimitById } from "./getSpendLimitById.js"; import { registerGetBudgetPrograms } from "./getBudgetPrograms.js"; import { registerGetBudgetProgramById } from "./getBudgetProgramById.js"; import { logError } from "../utils/logger.js"; import { ExpenseType, ExpenseStatus, ExpensePaymentStatus } from "../services/brex/expenses-types.js"; // Minimal request shape passed to individual tool handlers export type ToolCallRequest = { params: { name?: string; arguments?: Record<string, unknown> } }; // Store tool handlers export const toolHandlers = new Map<string, (request: ToolCallRequest) => Promise<unknown>>(); /** * Registers all tools with the server * @param server The MCP server instance */ export function registerTools(server: Server): void { // Register tool handlers registerGetTransactions(server); registerGetExpenses(server); registerGetAccountDetails(server); registerUploadReceipt(server); registerMatchReceipt(server); registerUpdateExpense(server); // Register pagination-aware tool handlers registerGetAllAccounts(server); registerGetAllExpenses(server); registerGetAllCardExpenses(server); registerGetCardTransactions(server); registerGetCashAccountStatements(server); registerGetExpenseById(server); registerGetCardExpenseById(server); registerGetCardStatementsPrimary(server); registerGetCashTransactions(server); // Read-only budget domain registerGetBudgets(server); registerGetBudgetById(server); registerGetSpendLimits(server); registerGetSpendLimitById(server); registerGetBudgetPrograms(server); registerGetBudgetProgramById(server); // Register the list tools handler registerListToolsHandler(server); // Register the call tool handler registerCallToolHandler(server); } /** * Registers the handler for listing available tools * @param server The MCP server instance */ function registerListToolsHandler(server: Server): void { server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "get_budgets", description: "List budgets (read-only). Example: {\"limit\":10}", inputSchema: { type: "object", properties: { limit: { type: "number" }, cursor: { type: "string" }, parent_budget_id: { type: "string" }, spend_budget_status: { type: "string", enum: ["ACTIVE","ARCHIVED","DRAFT"] } } } }, { name: "get_budget", description: "Get a budget by ID (read-only). Returns the complete budget object. Example: {\"budget_id\":\"budget_123\"}", inputSchema: { type: "object", properties: { budget_id: { type: "string", description: "The ID of the budget to retrieve" } }, required: ["budget_id"] } }, { name: "get_spend_limits", description: "List spend limits (read-only). Example: {\"limit\":10,\"status\":\"ACTIVE\"}", inputSchema: { type: "object", properties: { limit: { type: "number" }, cursor: { type: "string" }, parent_budget_id: { type: "string" }, status: { type: "string", enum: ["ACTIVE","ARCHIVED"] }, member_user_id: { type: "string" } } } }, { name: "get_spend_limit", description: "Get a spend limit by ID (read-only). Example: {\"id\":\"sl_123\"}", inputSchema: { type: "object", properties: { id: { type: "string" } }, required: ["id"] } }, { name: "get_budget_programs", description: "List budget programs (read-only). Returns complete budget program objects. Example: {\"limit\":10,\"budget_program_status\":\"ACTIVE\"}", inputSchema: { type: "object", properties: { limit: { type: "number" }, cursor: { type: "string" }, budget_program_status: { type: "string", enum: ["ACTIVE","INACTIVE"] } } } }, { name: "get_budget_program", description: "Get a budget program by ID (read-only). Example: {\"id\":\"bp_123\"}", inputSchema: { type: "object", properties: { id: { type: "string" } }, required: ["id"] } }, { name: "get_expense", description: "Get a single expense by ID. Returns the complete expense object. Example: {\"expense_id\":\"expense_123\",\"expand\":[\"merchant\"]}", inputSchema: { type: "object", properties: { expense_id: { type: "string", description: "Expense ID" }, expand: { type: "array", items: { type: "string" } } }, required: ["expense_id"] } }, { name: "get_card_expense", description: "Get a single card expense by ID. Returns the complete card expense object. Example: {\"expense_id\":\"expense_123\",\"expand\":[\"merchant\"]}", inputSchema: { type: "object", properties: { expense_id: { type: "string", description: "Card expense ID" }, expand: { type: "array", items: { type: "string" } } }, required: ["expense_id"] } }, { name: "get_card_statements_primary", description: "Get complete statements for the primary card account. Returns full statement objects. Example: {\"limit\":10}", inputSchema: { type: "object", properties: { cursor: { type: "string" }, limit: { type: "number" } } } }, { name: "get_cash_transactions", description: "LIST: Cash transactions (requires cash scopes). Example: {\"account_id\":\"cash_acc_123\",\"limit\":10}. Returns complete transaction objects.", inputSchema: { type: "object", properties: { account_id: { type: "string", description: "Cash account ID" }, cursor: { type: "string", description: "Pagination cursor" }, limit: { type: "number", description: "Items per page (1-100)" }, posted_at_start: { type: "string", description: "ISO timestamp to start from" }, expand: { type: "array", items: { type: "string" }, description: "Fields to expand" } }, required: ["account_id"] } }, { name: "get_card_transactions", description: "LIST: Primary card transactions. Returns complete transaction objects. Example: {\"limit\":10,\"posted_at_start\":\"2025-08-01T00:00:00Z\",\"expand\":[\"merchant\"]}", inputSchema: { type: "object", properties: { cursor: { type: "string", description: "Pagination cursor" }, limit: { type: "number", description: "Items per page (default 50)" }, user_ids: { type: "array", items: { type: "string" }, description: "Optional filter by user IDs" }, posted_at_start: { type: "string", description: "ISO timestamp to start from" }, expand: { type: "array", items: { type: "string" }, description: "Fields to expand" } } } }, { name: "get_cash_account_statements", description: "Get cash account statements by account ID. Returns complete statement objects. Example: {\"account_id\":\"cash_acc_123\",\"limit\":5}", inputSchema: { type: "object", properties: { account_id: { type: "string", description: "Cash account ID" }, cursor: { type: "string", description: "Pagination cursor" }, limit: { type: "number", description: "Items per page (default 50, max 100)" } }, required: ["account_id"] } }, { name: "get_transactions", description: "Get transactions for a Brex account", inputSchema: { type: "object", properties: { accountId: { type: "string", description: "ID of the Brex account" }, limit: { type: "number", description: "Maximum number of transactions to return (default: 50)" } }, required: ["accountId"] } }, { name: "get_expenses", description: "LIST (single page): Expenses with optional filters. Returns complete expense objects. Example: {\"limit\":5,\"status\":\"APPROVED\",\"expand\":[\"merchant\"]}", inputSchema: { type: "object", properties: { expense_type: { type: "string", enum: Object.values(ExpenseType), description: "Type of expenses to retrieve" }, status: { type: "string", enum: Object.values(ExpenseStatus), description: "Status filter for expenses" }, payment_status: { type: "string", enum: Object.values(ExpensePaymentStatus), description: "Payment status filter for expenses" }, limit: { type: "number", description: "Maximum number of expenses to return (default: 50)" }, expand: { type: "array", items: { type: "string" }, description: "Fields to expand (e.g., merchant, receipts)" } } } }, { name: "get_account_details", description: "Get detailed information about a Brex account", inputSchema: { type: "object", properties: { accountId: { type: "string", description: "ID of the Brex account" } }, required: ["accountId"] } }, { name: "upload_receipt", description: "Upload a receipt image to match with expenses", inputSchema: { type: "object", properties: { receipt_data: { type: "string", description: "Base64-encoded image data" }, receipt_name: { type: "string", description: "Name of the receipt file (e.g., 'receipt.jpg')" }, content_type: { type: "string", description: "MIME type of the receipt (e.g., 'image/jpeg')" } }, required: ["receipt_data", "receipt_name", "content_type"] } }, { name: "match_receipt", description: "Create a pre-signed URL for uploading a receipt that will be automatically matched with existing expenses", inputSchema: { type: "object", properties: { receipt_name: { type: "string", description: "Name of the receipt file (e.g., 'receipt.jpg')" }, receipt_type: { type: "string", description: "Type of the receipt (optional)" }, notify_email: { type: "string", description: "Email address to notify after matching (optional)" } }, required: ["receipt_name"] } }, { name: "update_expense", description: "Update an existing card expense", inputSchema: { type: "object", properties: { expense_id: { type: "string", description: "ID of the expense to update" }, memo: { type: "string", description: "Memo text to attach to the expense (optional)" }, category: { type: "string", description: "Category of the expense (optional)" }, budget_id: { type: "string", description: "ID of the budget to associate with the expense (optional)" }, department_id: { type: "string", description: "ID of the department to associate with the expense (optional)" }, location_id: { type: "string", description: "ID of the location to associate with the expense (optional)" }, custom_fields: { type: "array", description: "Custom fields to update (optional)", items: { type: "object", properties: { key: { type: "string", description: "Key of the custom field" }, value: { type: "object", description: "Value of the custom field" } } } } }, required: ["expense_id"] } }, // Pagination-aware tools { name: "get_all_accounts", description: "Get all Brex accounts with pagination support", inputSchema: { type: "object", properties: { page_size: { type: "number", description: "Number of items per page (default: 50, max: 100)" }, max_items: { type: "number", description: "Maximum total number of items to retrieve across all pages" }, status: { type: "string", enum: ["ACTIVE", "INACTIVE", "CLOSED"], description: "Filter accounts by status" } } } }, { name: "get_all_expenses", description: "LIST: Paginated expenses with filters. Returns complete expense objects. Example: {\"page_size\":5,\"max_items\":5,\"status\":[\"APPROVED\"],\"window_days\":7,\"min_amount\":100}", inputSchema: { type: "object", properties: { page_size: { type: "number", description: "Number of items per page (default: 50, max: 100)" }, max_items: { type: "number", description: "Maximum total number of items to retrieve across all pages" }, expense_type: { type: "array", items: { type: "string", enum: Object.values(ExpenseType) }, description: "Filter expenses by type" }, status: { type: "array", items: { type: "string", enum: Object.values(ExpenseStatus) }, description: "Filter expenses by status" }, payment_status: { type: "array", items: { type: "string", enum: Object.values(ExpensePaymentStatus) }, description: "Filter expenses by payment status" }, start_date: { type: "string", description: "Filter expenses created on or after this date (ISO format)" }, end_date: { type: "string", description: "Filter expenses created on or before this date (ISO format)" }, window_days: { type: "number", description: "Optional batching window in days to split large date ranges" }, min_amount: { type: "number", description: "Client-side minimum purchased_amount.amount filter" }, max_amount: { type: "number", description: "Client-side maximum purchased_amount.amount filter" }, expand: { type: "array", items: { type: "string" }, description: "Fields to expand (e.g., merchant, receipts)" } } } }, { name: "get_all_card_expenses", description: "LIST: Paginated card expenses (no expense_type needed). Returns complete card expense objects. Example: {\"page_size\":5,\"max_items\":5,\"window_days\":7,\"min_amount\":100}", inputSchema: { type: "object", properties: { page_size: { type: "number", description: "Number of items per page (default: 50, max: 100)" }, max_items: { type: "number", description: "Maximum total number of items to retrieve across all pages" }, status: { type: "array", items: { type: "string", enum: Object.values(ExpenseStatus) }, description: "Filter card expenses by status" }, payment_status: { type: "array", items: { type: "string", enum: Object.values(ExpensePaymentStatus) }, description: "Filter card expenses by payment status" }, start_date: { type: "string", description: "Filter card expenses created on or after this date (ISO format)" }, end_date: { type: "string", description: "Filter card expenses created on or before this date (ISO format)" }, merchant_name: { type: "string", description: "Filter card expenses by merchant name (partial match)" }, window_days: { type: "number", description: "Optional batching window in days to split large date ranges" }, min_amount: { type: "number", description: "Client-side minimum purchased_amount.amount filter" }, max_amount: { type: "number", description: "Client-side maximum purchased_amount.amount filter" }, expand: { type: "array", items: { type: "string" }, description: "Fields to expand (e.g., merchant, receipts)" } } } } ] }; }); } /** * Registers the handler for calling tools * @param server The MCP server instance */ function registerCallToolHandler(server: Server): void { server.setRequestHandler(CallToolRequestSchema, async (request) => { try { const handler = toolHandlers.get(request.params.name); if (!handler) { throw new Error(`Unknown tool: ${request.params.name}`); } const result = await handler(request as unknown as ToolCallRequest); return result as any; } catch (error) { logError(error as Error); throw error; } }); } // Helper function to register a tool handler export function registerToolHandler(name: string, handler: (request: ToolCallRequest) => Promise<unknown>): void { toolHandlers.set(name, handler); }

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/crazyrabbitLTC/mcp-brex-server'

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