tiller-mcp-server
MCP server for Tiller Money - query financial data via Google Sheets
Install / Use
claude mcp add jackstein21 -- npx -y github:jackstein21/tiller-mcp-serverIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
Finance & AccountingSupported Platforms
Skill content
View source on GitHubTiller Money MCP Server
A Model Context Protocol (MCP) server for Tiller Money's Google Sheets-based personal finance tracking. Enables natural language queries against your financial data through Claude Desktop with direct read-only access via the Google Sheets API and OAuth2 authentication.
Quick Start
1. Installation
-
Clone this repository:
git clone https://github.com/jackstein21/tiller-mcp-server.git cd tiller_mcp -
Set up Python environment:
# Using conda (recommended) conda create -n tiller_mcp python=3.12 conda activate tiller_mcp # Install dependencies pip install -r requirements.txt -
Set up Google Cloud Project:
Before authenticating, you need to create a Google Cloud Project and enable the Google Sheets API:
- Go to Google Cloud Console
- Create a new project (or select an existing one)
- Enable the Google Sheets API for your project
- Create OAuth 2.0 credentials (Desktop app type)
- Download the credentials JSON file
- Save it as
auth/credentials.jsonin this project
-
Authenticate with Google Sheets:
# Run the authentication setup script python auth/auth_setup.pyFollow the prompts:
- Your browser will open for Google OAuth consent
- Grant access to Google Sheets
- Authentication token will be saved to
auth/token.json
-
Configure Claude Desktop: Add this to your Claude Desktop configuration file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json{ "mcpServers": { "Tiller Money": { "command": "/opt/anaconda3/envs/tiller_mcp/bin/python", "args": [ "/path/to/your/tiller_mcp/src/tiller_mcp_server/server.py" ], "env": { "TILLER_SHEET_ID": "your_tiller_spreadsheet_id_here" } } } }Important:
- Replace
/path/to/your/tiller_mcpwith your actual project path - Replace
your_tiller_spreadsheet_id_herewith your Tiller spreadsheet ID - If not using conda, update the
commandpath to your Python interpreter
- Replace
-
Get your Tiller Spreadsheet ID:
- Open your Tiller spreadsheet in Google Sheets
- Copy the ID from the URL:
https://docs.google.com/spreadsheets/d/{SPREADSHEET_ID}/edit
-
Restart Claude Desktop
Features
Account Management
- View all active financial accounts
- Filter by account type (Credit Cards, Retirement, Savings, etc.)
Transaction Queries
- Search and filter transactions with powerful query options
- Date range filtering (start/end date)
- Account filtering (partial matching by account number)
- Category filtering (partial matching, case-insensitive)
- Amount filtering (min/max amounts for expenses or income)
- Description search across transaction text
- Pagination for large result sets
- Chronological sorting (most recent first)
- Detailed transaction lookup by ID
Category Management
- View all category definitions from Tiller
- Filter by category type (Expense, Income, Transfer)
- Filter by category group (Living, Fun, etc.)
- Optional monthly budget allocation data per category
Budget Analysis
- Access monthly budget allocations from Categories sheet
- Compare budgeted vs. actual spending
- Analyze any month or date range
- Natural language budget queries
Available Tools
Accounts
| Tool | Description | Parameters |
|------|-------------|------------|
| get_accounts | Get all active financial accounts | account_type (optional) - Filter by account type/group |
Transactions
| Tool | Description | Parameters |
|------|-------------|------------|
| get_transactions | Query transactions with filtering & pagination | start_date, end_date, account, category, min_amount, max_amount, description, limit, offset (all optional) |
| get_transaction_details | Get complete details for a single transaction | transaction_id (required) - 24-character hex ID |
Categories & Budgets
| Tool | Description | Parameters |
|------|-------------|------------|
| get_categories | Get all category definitions with optional monthly budgets | category_type (optional) - Filter by type (Expense/Income/Transfer)<br>group (optional) - Filter by group (partial match)<br>include_monthly_budgets (optional, default: false) - Include monthly budget data |
Usage Examples
Account Queries
Ask Claude natural language questions like:
- "Show me all my financial accounts"
- "Show me my credit card accounts"
- "List all my retirement accounts"
Transaction Queries
Query transactions using natural language:
- "Show me my 20 most recent transactions"
- "Show me all transactions in December 2025"
- "Get transactions between 12/01/2025 and 12/20/2025"
- "Show me transactions for account ending in 1234"
- "Show me all grocery transactions"
- "Find all dining expenses in December 2025"
- "Show me all expenses over $100"
- "List all income transactions"
- "Find transactions between $20 and $50"
- "Show me all Starbucks transactions"
- "Find all coffee shop purchases"
Combined Filters
Combine multiple criteria in one query:
- "Show me December 2025 transactions for account 1234"
- "Find dining expenses between $20 and $50 in December 2025"
- "Show all grocery transactions over $100"
Category Queries
Explore your category structure:
- "Show me all my categories"
- "List all expense categories"
- "What categories are in the Living group?"
- "Show expense categories in the Fun group"
Budget Analysis
Analyze budgets vs. actual spending:
- "Show me my budget for December 2025"
- "Get all expense categories with their monthly budgets"
- "How much did I spend on groceries in January vs. my budget?"
- "Which categories am I over budget in for this month?"
- "Show me my total budgeted vs. actual spending for December"
Data Structures
Account Object
Each account object contains:
| Field | Type | Description | Example |
|-------|------|-------------|---------|
| display_name | string | Account name with masked number | "CREDIT CARD (-XXXX)" |
| account_type | string | Account type/group from Tiller | "Credit Cards", "Retirement", "Savings" |
| account_number | string | Last 4 digits | "-XXXX" |
| is_hidden | boolean | Always false (hidden accounts excluded) | false |
Transaction Object
Each transaction object contains:
| Field | Type | Description | Example |
|-------|------|-------------|---------|
| date | string | Transaction date | "12/19/2025" |
| description | string | Merchant/description | "Coffee Shop Downtown" |
| category | string | Transaction category | "Restaurants" |
| amount | float | Amount (negative for expenses) | -15.75 |
| amount_str | string | Formatted amount string | "-$15.75" |
| account | string | Account display name | "CREDIT CARD (-XXXX)" |
| account_number | string | Last 4 digits of account | "XXXX" |
| institution | string | Financial institution | "Chase" |
| month | string | Month grouping | "12/01/25" |
| week | string | Week grouping | "12/15/25" |
| transaction_id | string | Unique 24-char hex ID | "123abc456def789012345678" |
| check_number | string | Check number if applicable | "" |
| full_description | string | Full uppercase description | "COFFEE SHOP DOWNTOWN" |
Category Object
Each category object contains:
| Field | Type | Description | Example |
|-------|------|-------------|---------|
| category | string | Category name (unique identifier) | "Groceries", "Dining Out", "Salary" |
| group | string | Category group/classification | "Living", "Fun", "Primary Income" |
| type | string | Category type | "Expense", "Income", "Transfer" |
| monthly_budgets | object (optional) | Monthly budget amounts | {"Jan": {"amount": 600.0, "amount_str": "$600.00"}, ...} |
Monthly Budgets Structure (when include_monthly_budgets=True):
- Contains 12 months: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
- Each month has:
amount(float): Parsed budget amount (e.g., 600.0)amount_str(string): Original currency string (e.g., "$600.00")
Data Privacy & Security
Read-Only Access
- v1.0 is completely read-only - No write operations to your spreadsheet
- Safe to use without risk of data corruption
- Future write operations will require explicit user consent
Local Execution
- MCP server runs locally on your machine via stdio
- No cloud deployment or data transmission to third parties
- Data never leaves your local environment
Authentication Security
- OAuth2 credentials stored in
auth/credentials.json(gitignored) - Access token stored in
auth/token.json(gitignored) - Tokens automatically refresh when expired
- Full Google OAuth security model
Hidden Accounts
- Hidden accounts are always excluded from results
- No option to include hidden accounts (by design)
- Ensures sensitive accounts remain private
Tiller Sheet Integration
The MCP server reads from standard Tiller Money spreadsheet tabs:
Accounts Sheet
Uses columns A-D for efficiency:
- Column A: Display name with masked number
- Column B: Class Override (not currently used)
- Column C: Group (account type)
- Column D: Hide flag
Transactions Sheet
Uses columns A-P for complete transaction data including date, description, category, amount, account, institution, and metadata.
Categories Sheet
Uses columns A-C for category definitions, with optional columns D-P for monthly budget allocations (12 months).
Technical Details
Project Structure
tiller_mcp/
├── auth/
│ ├── credentials.json # OAuth credentials (gitignored)
│ ├── token.json # OAuth token (gitignored)
│ └── auth_setup.py # Authentication setup script
├── src/tiller_mcp_server/
│ ├── __init__.py # Package initialization
│ ├── server.py # Main MCP server (FastMCP)
│ ├── sheets_client.py # Google Sheets API wrapper
│ └── tiller_schema.py # Pydantic models
├── config.json # Example Claude Desktop config
├── requirements.txt # Python dependencies
├── PRD.md # Product Requirements Document
└── README.md # This documentation
Architecture
Three-layer pattern for clean separation of concerns:
-
Data Models (tiller_schema.py)
- Pydantic models for type-safe data handling
- Account, Transaction, and Category models
- Currency parsing, date handling, and account number extraction
- Optional monthly budget data support
-
API Client (sheets_client.py)
- Google Sheets API authentication and connection
- Automatic token refresh handling
- Efficient sheet range queries with singleton pattern
-
MCP Tools (server.py)
- FastMCP framework with
@mcp.tool()decorators - Read-only operations with comprehensive validation
- JSON response formatting with helpful error messages
- FastMCP framework with
Troubleshooting
Authentication Issues
Error: "TILLER_SHEET_ID environment variable not set"
- Solution: Add
TILLER_SHEET_IDto Claude Desktop config underenvsection
Error: "Token file not found"
- Solution: Run
python auth/auth_setup.pyto create authentication token
Error: "Credentials are invalid and cannot be refreshed"
- Solution: Re-run authentication:
python auth/auth_setup.py
Server Connection Issues
Error: "Server transport closed unexpectedly" in Claude Desktop
- Solution: Check that the Python path in config is correct
- Solution: Verify all dependencies are installed: `pip install -r
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
84.2kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
73.4kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
ruflo
73.0k🌊 The original agent harness. Deploy intelligent multi-player swarms, coordinate autonomous workflows, and build conversational AI systems. Features adaptive memory, self-learning intelligence, federation, vector RAG integration, and native Claude Code / Codex / Hermes and many more Integrated
CowAgent
47.1kOpen-source super AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
