Skip to main content
Glama
KoltonG

Lunch Money MCP Server

by KoltonG
tdd.md7.72 kB
<div align="center"> # TDD <br/> Lunch Money MCP Server _Building on [**PRD**](./prd.md) - this document explains how we'll deliver essential transaction data access through MCP with 2 focused checkpoints._ </div> --- ## Table of Contents - [Architecture & Components](#architecture--components) - [Architecture Overview](#architecture-overview) - [Component 1: MCP Server Structure](#component-1-mcp-server-structure) - [Component 2: Async Tool Handler Pattern](#component-2-async-tool-handler-pattern) - [Implementation Checkpoints](#implementation-checkpoints) - [Sequencing Strategy](#sequencing-strategy) - [Checkpoint 1: MCP Server + Test Component](#checkpoint-1-mcp-server--test-component) - [Checkpoint 2: Categories and Tags Tools](#checkpoint-2-categories-and-tags-tools) --- ## 🏗️ Architecture & Components **(Engineers - Implementation Guide)** ### Architecture Overview Simple MCP server that registers essential tools for Lunch Money data access. Focuses on transactions, categories, and tags - the core data users need for financial analysis. The MCP SDK handles all protocol communication. ```mermaid graph LR A[Chat Client] subgraph "MCP Server" B[MCP Server] C[Tool: Get Transactions] D[Tool: Get Categories] E[Tool: Get Tags] end F[Lunch Money API] A <-->|MCP Protocol| B B <--> C B <--> D B <--> E C <--> |HTTP Request| F D <--> |HTTP Request| F E <--> |HTTP Request| F ``` Each component is a concrete implementation piece. The MCP SDK handles protocol communication - we build the server structure and tool handlers. ### **Component 1: MCP Server Structure** Basic MCP server setup using the TypeScript SDK with tool registration. **Technical Details:** ```typescript // src/index.ts import { McpServer } from "@modelcontextprotocol/sdk/server/mcp"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio"; import { handleGetTransactions, getTransactionsSchema, } from "./tools/getTransactions"; const server = new McpServer({ name: "lunch-money-mcp", version: "0.1.0", }); // Register tools with Zod schemas server.registerTool( "get_transactions", { title: "Get Transactions", description: "Fetch transactions from Lunch Money API", inputSchema: getTransactionsSchema, }, handleGetTransactions ); // Connect to transport const transport = new StdioServerTransport(); await server.connect(transport); ``` **Folder Structure:** - `src/index.ts` - Main server file - `src/tools/` - Tool handler functions with tests alongside - `src/tools/getTransactions.ts` - Tool handler - `src/tools/getTransactions.test.ts` - Tests for tool handler **Development Environment Requirements:** - **Bun Runtime:** Version 1.2.5 or higher required - **Version Management:** Create `.tool-versions` file with `bun 1.2.5` if: - File doesn't already exist in project root - Required bun version is not specified in existing file - Current system bun version doesn't meet minimum requirements - **Package Management:** Use `bun install` for dependency installation - **Build Target:** Configure for bun runtime (see tsconfig.json) **Package.json Scripts:** See `@rules/tech-stack.spec.md` for standard configuration and scripts. ### **Component 2: Async Tool Handler Pattern** Strongly-typed async tool handlers using Zod schemas for input validation and axios for external API calls. **Technical Details:** ```typescript // src/tools/getTransactions.ts import { z } from "zod"; import axios from "axios"; export const getTransactionsSchema = { start_date: z.string().optional().describe("Start date (YYYY-MM-DD)"), end_date: z.string().optional().describe("End date (YYYY-MM-DD)"), category_id: z.number().optional().describe("Filter by category ID"), }; export async function handleGetTransactions( args: z.infer<typeof getTransactionsSchema> ) { try { const { start_date, end_date, category_id } = args; // Build URL with query parameters using native URLSearchParams const url = new URL("https://dev.lunchmoney.app/v1/transactions"); if (start_date) url.searchParams.append("start_date", start_date); if (end_date) url.searchParams.append("end_date", end_date); if (category_id) url.searchParams.append("category_id", String(category_id)); const response = await axios.get(url.toString(), { headers: { Authorization: `Bearer ${process.env.LUNCH_MONEY_API_KEY}`, }, }); return { content: [ { type: "text", text: JSON.stringify(response.data, null, 2), }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error fetching transactions: ${error.message}`, }, ], isError: true, }; } } ``` **Recommended Organization:** - One file per tool handler in `src/tools/` - Export Zod schema for tool registration - Use native Web APIs (URLSearchParams, URL) instead of custom helpers - Use axios for HTTP requests with proper error handling - Proper error handling with `isError: true` - Test file alongside source: `src/tools/getTransactions.test.ts` **Testing:** Follow `@rules/test.spec.md` for all testing patterns and examples. --- ## 🎯 Implementation Checkpoints **(PMs - Validation & Demo Points)** ### Sequencing Strategy Ship fast with focused checkpoints that prove core MCP server functionality. This feature delivers essential transaction data access - additional API endpoints can be added in future features. ### Checkpoint 1: MCP Server + Test Component Get basic MCP server running with one simple tool to verify end-to-end communication using MCP Inspector. #### Requirements: **MCP Server Setup (Component 1)** - [ ] c1.r1 Given MCP TypeScript SDK and bun are installed - [ ] c1.r2 When server starts with `bun run start` - [ ] c1.r3 Then MCP Inspector (https://github.com/modelcontextprotocol/inspector) can connect - [ ] c1.r4 Then server advertises "get_transactions" tool in inspector **Test Tool Handler (Component 2)** - [ ] c1.r5 Given LUNCH_MONEY_API_KEY environment variable is set - [ ] c1.r6 When user calls "get_transactions" tool via MCP Inspector - [ ] c1.r7 Then tool handler returns transaction data or clear error - [ ] c1.r8 Then end-to-end MCP communication is verified **Unit Testing Setup** - [ ] c1.r9 Given test file `getTransactions.test.ts` exists alongside source - [ ] c1.r10 When running `bun test` - [ ] c1.r11 Then unit tests pass for getTransactions function patterns - [ ] c1.r12 Then test coverage shows handler input validation works correctly ### Checkpoint 2: Categories and Tags Tools Add two more tools using the proven Component 2 pattern to verify the approach scales to multiple endpoints. #### Requirements: **Categories Data Access** - [ ] c2.r1 Given the transactions tool works from Checkpoint 1 - [ ] c2.r2 When user asks "show me my spending categories" via MCP - [ ] c2.r3 Then user receives a list of all their categories - [ ] c2.r4 Then categories include names, descriptions, and budget settings **Tags Data Access** - [ ] c2.r5 Given the categories feature works - [ ] c2.r6 When user asks "show me my transaction tags" via MCP - [ ] c2.r7 Then user receives a list of all their tags - [ ] c2.r8 Then tags include names and descriptions **Complete Organization Data** - [ ] c2.r9 Given both categories and tags are accessible - [ ] c2.r10 When user needs to understand their transaction organization - [ ] c2.r11 Then user can access transactions, categories, and tags all through MCP - [ ] c2.r12 Then user has essential financial data access through MCP for analysis

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/KoltonG/Lunch-Money-MCP'

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