Skip to main content
Glama
crazyrabbitLTC

Brex MCP Server

get_expenses

Retrieve and filter expense data from Brex, including status, payment details, and merchant information for financial tracking and analysis.

Instructions

LIST (single page): Expenses with optional filters. Returns complete expense objects. Example: {"limit":5,"status":"APPROVED","expand":["merchant"]}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
expense_typeNoType of expenses to retrieve
statusNoStatus filter for expenses
payment_statusNoPayment status filter for expenses
limitNoMaximum number of expenses to return (default: 50)
expandNoFields to expand (e.g., merchant, receipts)

Implementation Reference

  • The core execution handler for the 'get_expenses' MCP tool. Validates parameters, fetches expenses from Brex API, filters valid items, and returns JSON-formatted response.
    registerToolHandler("get_expenses", async (request: ToolCallRequest) => {
      try {
        // Validate parameters
        const params = validateParams(request.params.arguments);
        logDebug(`Getting expenses with params: ${JSON.stringify(params)}`);
        
        // Get Brex client
        const brexClient = getBrexClient();
        
        // Set default limit if not provided
        const limit = params.limit || 50;
        
        try {
          // Prepare API parameters - use user-provided expand or default to empty
          const apiParams: ListExpensesParams = {
            limit,
            expand: params.expand || [] // Use provided expand array or default to empty for minimal response size
          };
          
          // Add filters if provided, ensuring expense_type is an array
          if (params.expense_type) {
            apiParams.expense_type = [params.expense_type];
          }
          
          if (params.status) {
            apiParams.status = [params.status];
          }
          
          if (params.payment_status) {
            apiParams.payment_status = [params.payment_status];
          }
          
          // Call Brex API to get expenses
          const expenses = await brexClient.getExpenses(apiParams);
          
          // Validate expenses data
          if (!expenses || !Array.isArray(expenses.items)) {
            throw new Error("Invalid response format from Brex API");
          }
          
          // Filter valid expenses
          const validExpenses = expenses.items.filter(isExpense);
          logDebug(`Found ${validExpenses.length} valid expenses`);
          
          const result = {
            expenses: validExpenses,
            meta: {
              total_count: validExpenses.length,
              requested_parameters: params
            }
          };
          return {
            content: [{
              type: "text",
              text: JSON.stringify(result, null, 2)
            }]
          };
        } catch (apiError) {
          logError(`Error calling Brex API: ${apiError instanceof Error ? apiError.message : String(apiError)}`);
          throw new Error(`Failed to get expenses: ${apiError instanceof Error ? apiError.message : String(apiError)}`);
        }
      } catch (error) {
        logError(`Error in get_expenses tool: ${error instanceof Error ? error.message : String(error)}`);
        throw error;
      }
    });
  • JSON input schema definition for the 'get_expenses' tool, registered in the listTools response.
      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)"
          }
        }
      }
    },
  • Invocation of registerGetExpenses to register the 'get_expenses' tool handler during server setup.
    registerGetExpenses(server);
  • Function that registers the 'get_expenses' tool handler with the internal toolHandlers map.
    export function registerGetExpenses(_server: Server): void {
      registerToolHandler("get_expenses", async (request: ToolCallRequest) => {
        try {
          // Validate parameters
          const params = validateParams(request.params.arguments);
          logDebug(`Getting expenses with params: ${JSON.stringify(params)}`);
          
          // Get Brex client
          const brexClient = getBrexClient();
          
          // Set default limit if not provided
          const limit = params.limit || 50;
          
          try {
            // Prepare API parameters - use user-provided expand or default to empty
            const apiParams: ListExpensesParams = {
              limit,
              expand: params.expand || [] // Use provided expand array or default to empty for minimal response size
            };
            
            // Add filters if provided, ensuring expense_type is an array
            if (params.expense_type) {
              apiParams.expense_type = [params.expense_type];
            }
            
            if (params.status) {
              apiParams.status = [params.status];
            }
            
            if (params.payment_status) {
              apiParams.payment_status = [params.payment_status];
            }
            
            // Call Brex API to get expenses
            const expenses = await brexClient.getExpenses(apiParams);
            
            // Validate expenses data
            if (!expenses || !Array.isArray(expenses.items)) {
              throw new Error("Invalid response format from Brex API");
            }
            
            // Filter valid expenses
            const validExpenses = expenses.items.filter(isExpense);
            logDebug(`Found ${validExpenses.length} valid expenses`);
            
            const result = {
              expenses: validExpenses,
              meta: {
                total_count: validExpenses.length,
                requested_parameters: params
              }
            };
            return {
              content: [{
                type: "text",
                text: JSON.stringify(result, null, 2)
              }]
            };
          } catch (apiError) {
            logError(`Error calling Brex API: ${apiError instanceof Error ? apiError.message : String(apiError)}`);
            throw new Error(`Failed to get expenses: ${apiError instanceof Error ? apiError.message : String(apiError)}`);
          }
        } catch (error) {
          logError(`Error in get_expenses tool: ${error instanceof Error ? error.message : String(error)}`);
          throw error;
        }
      });
    } 
  • Helper function to validate and sanitize input parameters according to the tool schema.
    function validateParams(input: any): GetExpensesParams {
      if (!input) {
        return {}; // All parameters are optional
      }
      
      const params: GetExpensesParams = {};
      
      // Validate expense_type if provided
      if (input.expense_type !== undefined) {
        if (!Object.values(ExpenseType).includes(input.expense_type)) {
          throw new Error(`Invalid expense_type: ${input.expense_type}`);
        }
        params.expense_type = input.expense_type;
      }
      
      // Validate status if provided
      if (input.status !== undefined) {
        if (!Object.values(ExpenseStatus).includes(input.status)) {
          throw new Error(`Invalid status: ${input.status}`);
        }
        params.status = input.status;
      }
      
      // Validate payment_status if provided
      if (input.payment_status !== undefined) {
        if (!Object.values(ExpensePaymentStatus).includes(input.payment_status)) {
          throw new Error(`Invalid payment_status: ${input.payment_status}`);
        }
        params.payment_status = input.payment_status;
      }
      
      // Validate limit if provided
      if (input.limit !== undefined) {
        const limit = parseInt(input.limit.toString(), 10);
        if (isNaN(limit) || limit <= 0) {
          throw new Error("Invalid limit: must be a positive number");
        }
        params.limit = limit;
      }
      
      // Validate expand if provided
      if (input.expand !== undefined) {
        if (Array.isArray(input.expand)) {
          params.expand = input.expand.map(String).filter((e: string) => e.trim().length > 0);
        } else {
          throw new Error("Invalid expand: must be an array of strings");
        }
      }
      
      return params;
    }

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