expense-log-mcp
Version:
A MCP server that provides tools for logging expenses.
220 lines (173 loc) • 5.92 kB
Markdown
for logging expenses.
- Log a new expense to a ledger.
- Delete an expense record.
- Retrieve a list of all available expense categories.
- Retrieve and group expenses by payer and category.
- [Node.js](https://nodejs.org/)
- A [PostgreSQL](https://www.postgresql.org/) database
1. **Clone the repository:**
```bash
git clone https://github.com/evanxd/expense-log-mcp.git
```
2. **Install dependencies:**
```bash
npm install
```
3. **Set up the database:**
- Create a `.env` file in the root of the project.
- Add your PostgreSQL connection string to the `.env` file:
```
DB_USER="postgres"
DB_HOST="localhost"
DB_PORT="5432"
DB_DATABASE="postgres"
DB_PASSWORD="YOUR_DB_PASSWORD"
DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE}?schema=public"
```
- Apply the database schema:
```bash
npx prisma db push
```
- Seed the database with initial categories:
```bash
npm run db:seed
```
4. **Build the project:**
```bash
npm run build
```
5. **Set up the MCP server:**
- Add the following configuration to your MCP host (e.g., Gemini CLI) settings:
```json
"mcpServers": {
"expense-log-mcp": {
"command": "node",
"args": [
"/path/to/expense-log-mcp/dist/index.js"
],
"env": {
"DATABASE_URL": "postgresql://postgres:YOUR_DB_PASSWORD@localhost:5432/postgres?schema=public"
}
}
}
```
The server exposes the following tools:
Adds a new expense record.
**Parameters:**
| Name | Type | Description |
|---------------|--------|----------------------------------------------------|
| `ledgerId` | string | The ID of the ledger to add the expense to. |
| `categoryId` | string | The ID of the expense category. |
| `messageId` | string | A unique ID for the message to prevent duplicates. |
| `description` | string | A description of the expense. |
| `amount` | number | The amount of the expense. |
| `payer` | string | The name of the person who paid. |
**Returns:**
A JSON string confirming the expense has been added, e.g.:
```json
{
"success": true,
"code": "OK",
"message": "Expense added successfully.",
"data": {
"expenseId": "clx...456"
}
}
```
Deletes an expense record.
**Parameters:**
| Name | Type | Description |
|-------------|--------|-----------------------------------------------------|
| `ledgerId` | string | The ID of the ledger the expense belongs to. |
| `messageId` | string | The unique message ID of the expense to be deleted. |
**Returns:**
A JSON string confirming the expense has been deleted, and including details of the deleted expense, e.g.:
```json
{
"success": true,
"code": "OK",
"message": "Expense deleted successfully.",
"data": {
"id": "clx...123",
"description": "Lunch",
"amount": 15.75,
"createdAt": "Sun Sep 07 2025"
}
}
```
Retrieves the list of all expense categories.
**Parameters:**
None.
**Returns:**
A JSON string containing the list of expense categories, e.g.:
```json
{
"success": true,
"code": "OK",
"message": "Expense categories retrieved successfully.",
"data": [
{
"expenseCategoryId": "clx...1",
"expenseCategoryName": "Transportation"
},
{
"expenseCategoryId": "clx...2",
"expenseCategoryName": "Utilities"
}
]
}
```
Retrieves and groups expenses by payer and then by category name, returning the total amount for each category,
with optional filters for category IDs, payer, and a date range.
**Parameters:**
| Name | Type | Description |
|---------------|----------|--------------------------------------------------------------------|
| `ledgerId` | string | The ID of the ledger to retrieve expenses from. |
| `categoryIds` | string[] | Optional. An array of category IDs to filter by. |
| `payer` | string | Optional. The name of the payer to filter by. |
| `startDate` | string | Optional. The start date for filtering expenses (ISO 8601 format). |
| `endDate` | string | Optional. The end date for filtering expenses (ISO 8601 format). |
**Returns:**
A JSON string containing the grouped expenses, e.g.:
```json
{
"success": true,
"code": "OK",
"message": "Grouped expenses retrieved successfully.",
"data": {
"Payer1": {
"expenseCategories": {
"Entertainment": 100,
"Transportation": 50
},
"totalAmount": 150
},
"Payer2": {
"expenseCategories": {
"Dining/Snacks": 75
},
"totalAmount": 75
}
}
}
```
This project uses Prisma to manage the database schema. The schema is defined in `prisma/schema.prisma` and includes the following models:
- `Ledger`: Represents a collection of expenses.
- `ExpenseCategory`: Represents a category for an expense.
- `Expense`: Represents a single expense record. A unique constraint is added on `ledgerId` and `messageId` to prevent duplicate expenses.
All models include `createdAt` and `updatedAt` timestamps. IDs are generated using `cuid()`.
Contributions are welcome! Please feel free to submit a pull request.
This project is licensed under the [MIT License](LICENSE).
A MCP server that provides tools