Skip to main content
Glama
andreajrubino

expense-tracker

README.md
# Expense Tracker MCP Server

Enterprise-grade documentation for a Python-based Model Context Protocol
(MCP) expense tracking server.

> **⚠️ Proof of Concept (PoC)**
>
> This is a quick and dirty implementation based on frameworks and libraries available as of February 2026.
>
> Behavior, APIs, and integration patterns may evolve in future versions of FastMCP, OpenAI Codex, and related tooling.
> This is just for demonstrative purposes
>


------------------------------------------------------------------------

## Table of Contents

1.  Introduction
2.  Architecture Overview
3.  Environment Setup (uv-based)
4.  Installed Packages
5.  Project Structure
6.  MCP Server Overview
7.  Core Functional Components
8.  Excel Storage Layer
9.  Running the Server
10. Testing with MCP Inspector
11. Integrating with Codex in VS Code
12. Operational Considerations
13. Future Improvements

------------------------------------------------------------------------

# 1. Introduction

This project implements a local **Model Context Protocol (MCP) server**
using Python and FastMCP.

> 📢 **Educational Proof of Concept**
>
> This repository contains intentionally simple and demonstrative code designed
> to get started with MCP servers and understand how they work.
> The implementation prioritizes clarity and approachability over production-grade
> architecture, advanced patterns, or highly optimized design.

The server allows natural-language expense logging such as:

> "I spent 20 dollars on a Batman figure yesterday"

The server:
- Parses the amount  
- Detects currency  
- Extracts relative or explicit dates  
- Stores the result in an Excel file  
- Exposes tools via MCP for AI agents (e.g., OpenAI Codex in VS Code)

This project demonstrates:

- Local stdio-based MCP server design  
- Natural language parsing  
- Structured data persistence  
- Tool registration via FastMCP  
- Integration with OpenAI Codex UI  


### Example result in Codex on VS Code
![MCP Architecture](assets/screens/example-function.png)

------------------------------------------------------------------------

# 2. Architecture Overview

The solution consists of:

-   FastMCP stdio server
-   Natural language parser
-   Excel persistence layer (openpyxl)
-   Tool registration via decorators
-   Local stdio transport for MCP communication

Transport Type: - STDIO (standard input/output)

Data Storage: - Excel file (`expenses.xlsx`)

Execution Model: - Event-driven tool invocation

------------------------------------------------------------------------

# 3. Environment Setup (uv-based)

The environment was configured using `uv` for fast dependency
management.

## Initialize project

``` powershell
uv init
```

## Add required packages

``` powershell
uv add fastmcp openpyxl dateparser pypandoc
```

This creates:

-   Virtual environment
-   Dependency resolution
-   Lockfile
-   Reproducible environment

------------------------------------------------------------------------

# 4. Installed Packages

  Package      Purpose
  ------------ -------------------------------
  fastmcp      MCP server implementation
  openpyxl     Excel read/write operations
  dateparser   Natural language date parsing
  pypandoc     Documentation generation
  re           Regex amount parsing
  pathlib      File handling
  datetime     Timestamp management

------------------------------------------------------------------------

# 5. Project Structure

    project-root/
    │
    ├── server.py
    ├── expenses.xlsx
    ├── README.md
    └── .venv/

------------------------------------------------------------------------

# 6. MCP Server Overview

The server is initialized as:

``` python
mcp = FastMCP("expense-tracker")
```

Tools are registered using:

``` python
@mcp.tool
```

The server starts via:

``` python
if __name__ == "__main__":
    mcp.run()
```

The server communicates using STDIO and must not print to stdout.

------------------------------------------------------------------------

# 7. Core Functional Components

## 7.1 \_parse_amount(raw)

Extracts numeric amount using regex. Handles: - 12.000,16 - 12,000.16 -
12000

Returns:

    float

------------------------------------------------------------------------

## 7.2 \_parse_currency(raw)

Detects: - \$ → USD - € → EUR - £ → GBP - keyword matches (dollars,
euro, etc.)

Returns ISO currency code.

------------------------------------------------------------------------

## 7.3 \_parse_date_iso(raw)

Uses:

    dateparser.search.search_dates()

Configuration: - PREFER_DATES_FROM = "past" - RELATIVE_BASE =
datetime.now() - RETURN_AS_TIMEZONE_AWARE = False

Returns:

    YYYY-MM-DD

Fallback: - If no date detected → today

------------------------------------------------------------------------

## 7.4 \_parse_expense(text)

Combines: - amount - currency - date - description

Returns structured dictionary:

``` python
{
    "amount": float,
    "currency": str,
    "date_iso": str,
    "description": str
}
```

------------------------------------------------------------------------

# 8. Excel Storage Layer

Excel file created if missing:

    expenses.xlsx

Header structure:

    ["Date", "Description", "Amount", "Currency", "Raw Text", "Logged At"]

Append logic ensures: - Workbook exists - Correct sheet name - ISO
timestamp logging

Read logic: - Dynamically maps header row - Avoids tuple index errors -
Skips blank rows

------------------------------------------------------------------------

# 9. Running the Server

## Direct execution

``` powershell
.\.venv\Scripts\python.exe server.py
```

The process should remain running (stdio server).

------------------------------------------------------------------------

# 10. Testing with MCP Inspector

Launch:

``` powershell
npx @modelcontextprotocol/inspector python server.py
```

Steps: 1. Open browser UI 2. View tools 3. Call `log_expense` 4. Call
`list_expenses`

------------------------------------------------------------------------

# 11. Integrating with Codex in VS Code

## Open Codex MCP UI

"Connect to a custom MCP"

Select: - STDIO

## Configuration

**Command to launch:**

    C:\Users\andre\Documents\Python\MCP\Python\Stdio Server\.venv\Scripts\python.exe

**Arguments:**

    C:\Users\andre\Documents\Python\MCP\Python\Stdio Server\server.py

No environment variables required.

After saving: - Enable the MCP tool - Use in Codex chat:

Example:

    Log this expense: I spent 50 dollars on groceries yesterday

------------------------------------------------------------------------

# 12. Operational Considerations

-   Do not print to stdout
-   Use stderr for debugging
-   Always use absolute python path
-   Ensure virtual environment consistency
-   Keep Excel closed during writes
-   Consider file locking for production use

------------------------------------------------------------------------

# 13. Future Improvements

-   Category auto-detection
-   Deduplication logic
-   CSV export
-   SQLite backend
-   Multi-user storage
-   Authentication layer
-   Cloud deployment (HTTP MCP)
-   Structured validation with Pydantic

------------------------------------------------------------------------

TDQS

C2.5/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: listing expenses and logging a new expense. There is no overlap in functionality.

Naming Consistency5/5

Both tool names follow a consistent verb_noun pattern with snake_case (list_expenses, log_expense).

Tool Count3/5

With only 2 tools, the server feels underdeveloped for an expense tracker, which typically requires at least CRUD operations. However, the count is not extreme for a minimal prototype.

Completeness2/5

The tool set lacks essential operations like updating or deleting expenses, and log_expense has no description, making it incomplete for basic expense management.

Maintenance

ActivityInactive
ResponsivenessNo issues