# Splitwise MCP Server
A Model Context Protocol (MCP) server that enables AI assistants like Claude to manage Splitwise expenses with atomic duplicate prevention.
## Features
- **Atomic Duplicate Prevention**: Reserve-then-create pattern prevents accidental duplicate expenses from race conditions
- **Smart Duplicate Detection**: Fuzzy matching on description, amount, and date within configurable windows
- **Local SQLite Cache**: Fast duplicate checks without excessive API calls
- **Flexible Split Ratios**: Support for any split percentage (50/50, 75/25, 100/0, etc.)
- **Order ID Tracking**: Link expenses back to source orders (Amazon, Instacart, etc.) for traceability
## Requirements
- Python 3.10+
- Splitwise API key
- MCP-compatible client (Claude Code, etc.)
## Installation
```bash
# Clone the repository
git clone https://github.com/vishnujayvel/splitwise-mcp.git
cd splitwise-mcp
# Install in development mode
pip install -e .
# Or install with dev dependencies for testing
pip install -e .[dev]
```
## Configuration
The server supports multiple configuration methods, checked in this order:
### Option 1: Environment Variables (Recommended for production)
```bash
export SPLITWISE_API_KEY="your_api_key"
export SPLITWISE_GROUP_ID="your_group_id"
export SPLITWISE_PAYER_ID="your_user_id"
export SPLITWISE_PARTNER_ID="partner_user_id"
# Optional: custom config file path
export SPLITWISE_CONFIG_PATH="/path/to/config.json"
# Optional: logging level (DEBUG, INFO, WARNING, ERROR)
export LOG_LEVEL="INFO"
# Optional: custom cache database path
export SPLITWISE_CACHE_PATH="./splitwise_cache.db"
```
### Option 2: Configuration File
Create a `config.json` file (see `config.example.json`):
```json
{
"splitwise": {
"api_key": "YOUR_SPLITWISE_API_KEY",
"group_id": "YOUR_GROUP_ID",
"payer_id": "YOUR_USER_ID",
"partner_id": "PARTNER_USER_ID"
}
}
```
### Getting Your Splitwise Credentials
1. **API Key**:
- Go to https://secure.splitwise.com/apps
- Click "Register your application"
- Fill in the application details
- Copy the API key
2. **User IDs and Group ID**:
- Go to https://secure.splitwise.com/api/v3.0/get_current_user (with authentication)
- Or use the Splitwise API to query your groups and members
- Your user ID and your partner's user ID are in the group members list
## Usage with Claude Code
Add to your `.mcp.json` file:
```json
{
"mcpServers": {
"splitwise": {
"command": "python",
"args": ["-m", "splitwise_mcp.server"],
"cwd": "/path/to/splitwise-mcp/src",
"env": {
"SPLITWISE_API_KEY": "your_api_key",
"SPLITWISE_GROUP_ID": "your_group_id",
"SPLITWISE_PAYER_ID": "your_user_id",
"SPLITWISE_PARTNER_ID": "partner_user_id"
}
}
}
}
```
## MCP Tools
### splitwise_check_duplicate
Check if an expense would be a duplicate based on description, amount, and date similarity.
**Input:**
```json
{
"description": "Amazon - Electronics",
"amount": 49.99,
"date": "2024-12-30",
"group_id": "YOUR_GROUP_ID"
}
```
**Output:**
```json
{
"is_duplicate": false,
"reason": "No duplicate found",
"existing_expense_id": null,
"similarity_score": 0.0
}
```
### splitwise_reserve_expense
Atomically reserve an expense slot to prevent race conditions. Must be called before creating an expense.
**Input:**
```json
{
"description": "Amazon - Electronics",
"amount": 49.99,
"date": "2024-12-30",
"group_id": "YOUR_GROUP_ID",
"order_id": "123-4567890-1234567"
}
```
**Output:**
```json
{
"reservation_id": "temp_abc123def456",
"expires_at": "2024-12-30T12:05:00",
"is_duplicate": false,
"reason": "Reservation created successfully",
"existing_expense_id": null
}
```
### splitwise_create_expense
Create an expense in Splitwise and confirm the reservation.
**Input:**
```json
{
"reservation_id": "temp_abc123def456",
"description": "Amazon - Electronics",
"amount": 49.99,
"date": "2024-12-30",
"group_id": "YOUR_GROUP_ID",
"payer_id": "YOUR_USER_ID",
"partner_id": "PARTNER_USER_ID",
"order_id": "123-4567890-1234567",
"split_ratio": "50/50"
}
```
**Output:**
```json
{
"status": "created",
"expense_id": "987654321",
"payer_owes": 24.99,
"partner_owes": 25.00,
"total": 49.99,
"url": "https://secure.splitwise.com/#/expenses/987654321"
}
```
### splitwise_sync_cache
Sync the local cache with Splitwise API. Fetches recent expenses and updates the cache.
**Input:**
```json
{
"group_id": "YOUR_GROUP_ID",
"since_date": "2024-12-01",
"limit": 100
}
```
**Output:**
```json
{
"synced_count": 15,
"last_sync_at": "2024-12-30T12:00:00",
"cache_size": 42
}
```
### splitwise_get_expenses
Query expenses from the local cache (fast, no API call).
**Input:**
```json
{
"group_id": "YOUR_GROUP_ID",
"start_date": "2024-12-01",
"end_date": "2024-12-31"
}
```
**Output:**
```json
{
"expenses": [
{
"id": "987654321",
"description": "Amazon - Electronics",
"amount": 49.99,
"date": "2024-12-30",
"payer_owes": 24.99,
"partner_owes": 25.00
}
],
"total_count": 1
}
```
### splitwise_delete_expense
Delete an expense from Splitwise and remove it from the cache.
**Input:**
```json
{
"expense_id": "987654321",
"group_id": "YOUR_GROUP_ID"
}
```
**Output:**
```json
{
"status": "deleted",
"expense_id": "987654321"
}
```
### splitwise_find_by_order_id
Find an expense by order ID (most reliable duplicate detection method).
**Input:**
```json
{
"order_id": "123-4567890-1234567"
}
```
**Output:**
```json
{
"found": true,
"expense": {
"expense_id": "987654321",
"description": "Amazon - Electronics",
"cost": 49.99,
"date": "2024-12-30",
"order_id": "123-4567890-1234567",
"group_id": "YOUR_GROUP_ID"
}
}
```
## Known Limitations
This is an early release optimized for **two-person expense splitting** (couples, roommates). The following features are not yet supported:
| Feature | Status | Notes |
|---------|--------|-------|
| Groups with 3+ members | Not supported | Hardcoded to payer + partner |
| Multiple groups | Not supported | Single group_id in config |
| Variable payer | Not supported | Payer always pays upfront |
| Expense categories | Not supported | - |
| Balance queries | Not supported | Use Splitwise app |
| Payment/settle-up | Not supported | Use Splitwise app |
| Expense editing | Not supported | Delete and recreate |
| Receipt images | Not supported | - |
Contributions welcome for any of these features!
## Troubleshooting
### "Missing required configuration fields"
Ensure all required environment variables or config file fields are set:
- `SPLITWISE_API_KEY` / `api_key`
- `SPLITWISE_GROUP_ID` / `group_id`
- `SPLITWISE_PAYER_ID` / `payer_id`
- `SPLITWISE_PARTNER_ID` / `partner_id`
### "Splitwise API error 401"
Your API key is invalid or expired. Generate a new one at https://secure.splitwise.com/apps
### "Reservation expired"
Reservations expire after 5 minutes. Create the expense immediately after reserving, or reserve again.
### Duplicate not detected
1. Run `splitwise_sync_cache` to update the local cache
2. Check that the expense date is within the duplicate detection window (default: 7 days)
## Development
```bash
# Install dev dependencies
pip install -e .[dev]
# Run tests
PYTHONPATH=src pytest tests/ -v
# Run the server for testing
python -m splitwise_mcp.server
```
## License
MIT License - see [LICENSE](LICENSE) file for details.