FreshBooks MCP Server
CHEVS Garage — FreshBooks MCP + Call Processor
Two systems in one repo:
FreshBooks MCP server — 29 tools that let Claude query and update FreshBooks directly (invoices, clients, estimates, expenses, payments, timesheets, reports).
Call Processor — records customer phone calls, transcribes them locally with Whisper, extracts job details with Claude, and automatically creates FreshBooks clients/estimates + schedules follow-up reminders.
Cost: $0/month beyond your existing Claude Code subscription.
Quick Start
Full setup from a new machine: follow SETUP.md.
FreshBooks MCP only (no call processor): follow GETTING_STARTED.md.
git clone https://github.com/zeal-tristian-chevier/containerized-freshbooks-mcp.git
cd containerized-freshbooks-mcpCall Processor — How It Works
Phone call ends
↓
Cube ACR auto-uploads audio to Google Drive (Android)
or iOS 18 one-tap share to Google Drive (iPhone)
↓
Google Drive for Desktop syncs to watch_folder/ on your PC/Mac
↓
Docker container detects the new file (runs 24/7)
↓
Whisper transcribes audio locally — free, no internet needed
↓
Claude extracts: customer, ATV, work needed, parts, follow-ups
↓
FreshBooks: client created/updated + estimate created
↓
Email summary sent + follow-up reminders queuedFreshBooks MCP — Tools (29 total)
Time tracking
check_timesheet— report logged/missing/under-logged days for a day, week, or monthlog_time— log hours per weekday against a project, with PTO exclusion and dry-run
Clients & estimates
list_clients·create_clientlist_estimates·create_estimate
Invoices & payments
list_invoices·get_invoice·create_invoice·update_invoice·send_invoice·void_invoicelist_payments·apply_payment·delete_payment
Expenses
list_expenses·create_expense·list_expense_categories
Items, taxes & services
list_items·create_itemlist_taxes·create_taxlist_services·list_staff
Projects & reports
list_projects·list_recurring_invoicesget_profit_loss·get_income_summary·get_accounts_aging
Architecture
Module | Responsibility |
| MCP interface — 29 tool definitions + testable |
| HTTP wrapper: auth injection, 401→refresh→retry, pagination |
| OAuth2 lifecycle: refresh, token rotation, bootstrap CLI |
| Pluggable storage: OS keychain or Fernet-encrypted file |
| Pure date math, unit conversion, report building |
| Orchestrates transcribe → extract → FreshBooks → notify |
| Local Whisper transcription (faster-whisper, CPU) |
| Runs |
| FreshBooks client/estimate creation |
| APScheduler + SQLite reminder queue |
| watchdog folder monitor |
Configuration
All settings in .env (copy from .env.example).
FreshBooks OAuth — credentials from my.freshbooks.com → Developer → your app:
Variable | Required | Notes |
| ✅ | OAuth app client id |
| ✅ | OAuth app secret |
| ✅ | Must exactly match the app setting (e.g. |
| — |
|
| — | Encrypted token file path (file backend) |
| — | Fernet key for file backend |
| — | Timezone for day boundaries (default |
| — | Expected hours/day (default |
Call Processor:
Variable | Notes |
|
|
| Your email — receives a summary after each call |
| Employee email for task reminders |
| Gmail credentials (use an App Password) |
Docker
Two containers, two Dockerfiles:
File | What it builds |
| MCP server — used by Claude Code/Desktop to query FreshBooks |
| Call processor — runs 24/7, watches for new audio files |
Start the call processor:
# Windows
.\docker-start.ps1
# macOS
bash docker-start.shRegister the MCP server with Claude Code (.mcp.json):
{
"mcpServers": {
"freshbooks": {
"command": "docker",
"args": ["compose", "-f", "/ABS/PATH/TO/docker-compose.yml", "run", "--rm", "-T", "app"]
}
}
}API Notes
Verified live against the FreshBooks v3 API:
Two hosts. Auth on
https://auth.freshbooks.com/oauth/authorize; all data calls onhttps://api.freshbooks.com.Rotating refresh tokens. Each refresh invalidates the old token. The new token is persisted before use, under a lock.
Time entries use
businessId(not accountId).durationis in seconds;started_atis UTC with milliseconds +Z.Date filters on payments/expenses are silently ignored by the API — filtering is done client-side after fetching.
Expense category names are always null in the v3 API for system categories.
Accounts aging report returns 404 on some account types — falls back to computing aging from outstanding invoice data.
Security
Token storage — OS keychain by default; encrypted-file fallback uses Fernet with the key in env (never co-located with the ciphertext),
0600permissions, and atomic writes.No secret leakage —
TokenSetmasks values inrepr; token payloads are never logged.Safe writes —
log_timerequires an explicitproject_id, defaults toskip_existing=true, supportsdry_run, never logs weekends.Compromise recovery — revoke in the FreshBooks Developer Portal, then re-run
freshbooks-mcp-auth.
Development
pytest # unit tests
# or in Docker:
docker build --target test -t freshbooks-mcp:test . && docker run --rm freshbooks-mcp:testLicense
Internal / private. Not licensed for distribution.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/zeal-tristian-chevier/containerized-freshbooks-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server