FreeAgent MCP Server
A Model Context Protocol server for the FreeAgent accounting API, enabling LLMs to manage contacts, invoices, estimates, bills, expenses, timeslips, projects, tasks, bank accounts, and more.
README
FreeAgent MCP Server
A Model Context Protocol (MCP) server for the FreeAgent accounting API. Enables LLMs to manage contacts, invoices, estimates, bills, expenses, timeslips, projects, tasks, bank accounts, and more.
By my own admission, most of this project is vibe coded.
Features
- Broad FreeAgent coverage: contacts, invoices (incl. transitions and discounts), estimates (incl. transitions), bills, recurring invoices, price list items, expenses, timeslips, projects, tasks, bank accounts, bank transaction explanations, categories, company info, and users
- Intent-bundle tools:
reconcile_bank_transaction,log_expense, andinvoice_from_timeslipscollapse multi-call sequences into single tool calls and resolve human-friendly hints (names, codes, references) to FreeAgent URLs server-side - Optional tool-search mode (
FREEAGENT_TOOL_SEARCH=true): collapses the tool catalog behind two meta-tools (freeagent_search_tools,freeagent_call_tool) so clients only pay the tool-definition token cost for tools they actually use - MCP elicitation:
create_invoicefalls back to a form elicitation whencontactis omitted (on clients that support it) - Two deployment modes: local (stdio) or cloud (Vercel serverless via Streamable HTTP)
- OAuth 2.0: stateless JWT-based auth for serverless, or direct token for local use
- Tool annotations:
readOnlyHint,destructiveHint,idempotentHint,openWorldHinton every tool - Zod validation: strict input schemas with
.describe()on all fields - Dual response formats: Markdown (human-readable) or JSON (structured)
- Pagination: proper header parsing with
x-total-countandLinkheaders - Rate limit handling: clear error messages with retry-after guidance
- Sandbox support: test safely against FreeAgent's sandbox environment
Deployment Options
Local (stdio) - for Claude Desktop
-
Install and build:
bun install bun run build -
Set environment variables:
export FREEAGENT_ACCESS_TOKEN="your_access_token" export FREEAGENT_USE_SANDBOX="true" # optional -
Add to Claude Desktop config (
~/Library/Application Support/Claude/claude_desktop_config.json):{ "mcpServers": { "freeagent": { "command": "node", "args": ["/path/to/freeagent-mcp-server/dist/index.js"], "env": { "FREEAGENT_ACCESS_TOKEN": "your_token", "FREEAGENT_USE_SANDBOX": "true" } } } }
Vercel (Streamable HTTP) - for cloud access
See VERCEL_DEPLOYMENT.md for full instructions. Key points:
- Uses
StreamableHTTPServerTransportin stateless mode (no sessions) - OAuth 2.0 with PKCE via JWT-encoded tokens (no database needed)
- Handles
POST(tool calls),GET(SSE streaming), andDELETE(returns 405 - stateless) - Set
PRODUCTION_URLenv var for stable OAuth callback URLs
Required env vars: FREEAGENT_CLIENT_ID, FREEAGENT_CLIENT_SECRET
Tool-Search Mode (optional)
By default the server registers every catalog tool directly, which makes all ~50 tool definitions part of the MCP client's tools/list response. For clients with many connected MCP servers — where tool-definition tokens add up quickly — set:
export FREEAGENT_TOOL_SEARCH=true
In this mode the server exposes only two meta-tools:
| Tool | Purpose |
|---|---|
freeagent_search_tools |
Search the catalog and return JSONSchema for matching tools. Query forms: select:name1,name2 for direct lookup, +required optional for scored search with required keywords, or plain keywords for a ranked search. |
freeagent_call_tool |
Invoke any catalog tool by name with validated arguments ({ name, arguments }). Pair with search_tools to discover schemas on demand. |
The full catalog is still reachable — it's just loaded on demand. This mirrors the deferred-loading pattern used by Claude Code's internal ToolSearch.
Available Tools
See TOOLS.md for per-tool parameters and examples. Summary:
Contacts
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_contacts |
List contacts with pagination and sorting | Yes |
freeagent_get_contact |
Get contact details by ID | Yes |
freeagent_create_contact |
Create a new contact | No |
Invoices
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_invoices |
List invoices with status/contact/project filters | Yes |
freeagent_get_invoice |
Get invoice details (renders computed discount amount) | Yes |
freeagent_create_invoice |
Create a draft invoice (supports discount_percent; elicits contact if omitted) |
No |
freeagent_transition_invoice |
mark_as_sent / mark_as_cancelled / mark_as_draft / mark_as_scheduled / convert_to_credit_note | No |
freeagent_invoice_from_timeslips |
Intent bundle: draft an invoice from a contact's unbilled timeslips | No |
Estimates
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_estimates |
List estimates with status/contact/project filters | Yes |
freeagent_get_estimate |
Get estimate details (renders computed discount amount) | Yes |
freeagent_create_estimate |
Draft an estimate (supports discount_percent) |
No |
freeagent_transition_estimate |
mark_as_sent / mark_as_approved / mark_as_rejected / mark_as_cancelled / mark_as_draft / convert_to_invoice | No |
Bills
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_bills |
List supplier bills with filters | Yes |
freeagent_get_bill |
Get bill details | Yes |
freeagent_create_bill |
Record a supplier bill | No |
Recurring Invoices
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_recurring_invoices |
List recurring invoice templates | Yes |
freeagent_get_recurring_invoice |
Get template details | Yes |
Price List Items
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_price_list_items |
List catalog items | Yes |
freeagent_get_price_list_item |
Get catalog item details | Yes |
freeagent_create_price_list_item |
Add a catalog item | No |
Expenses
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_expenses |
List expenses with date/view filters | Yes |
freeagent_get_expense |
Get expense details (inc. mileage info) | Yes |
freeagent_create_expense |
Create expense or mileage claim (with attachments) | No |
freeagent_update_expense |
Update an existing expense | No |
freeagent_log_expense |
Intent bundle: log a regular expense with a positive amount + kind enum |
No |
Timeslips
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_timeslips |
List time entries with filters | Yes |
freeagent_get_timeslip |
Get timeslip details | Yes |
freeagent_create_timeslip |
Create a time entry | No |
freeagent_update_timeslip |
Update a timeslip (incl. billed_on_invoice) |
No |
Bank Accounts & Transactions
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_bank_accounts |
List all bank accounts | Yes |
freeagent_get_bank_account |
Get bank account details | Yes |
freeagent_list_bank_transactions |
List transactions for an account | Yes |
freeagent_get_bank_transaction |
Get bank transaction details | Yes |
freeagent_list_bank_transaction_explanations |
List transaction explanations | Yes |
freeagent_get_bank_transaction_explanation |
Get explanation details | Yes |
freeagent_create_bank_transaction_explanation |
Explain/categorize a bank transaction | No |
freeagent_update_bank_transaction_explanation |
Update a transaction explanation | No |
freeagent_reconcile_bank_transaction |
Intent bundle: explain a transaction with a category name / invoice ref / bill ref | No |
Projects & Tasks
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_projects |
List projects with status/contact filters | Yes |
freeagent_get_project |
Get project details | Yes |
freeagent_create_project |
Create a new project | No |
freeagent_list_tasks |
List tasks with project/status filters | Yes |
freeagent_get_task |
Get task details | Yes |
freeagent_create_task |
Create a task within a project | No |
Categories, Company & Users
| Tool | Description | Read-only |
|---|---|---|
freeagent_list_categories |
List accounting categories | Yes |
freeagent_get_category |
Get category by nominal code | Yes |
freeagent_get_company |
Get company information | Yes |
freeagent_list_users |
List all users | Yes |
Development
Prerequisites
- Bun (used for package management and running scripts)
- Node.js 22.x
Setup
bun install
Scripts
| Command | Description |
|---|---|
bun run build |
Compile TypeScript |
bun run dev |
Watch mode (auto-recompile) |
bun run start |
Run the compiled server |
bun run lint |
Run ESLint |
bun run test |
Run tests |
bun run test:watch |
Run tests in watch mode |
bun run test:coverage |
Run tests with coverage |
Project Structure
freeagent-mcp-server/
├── src/
│ ├── index.ts # Stdio server entry point
│ ├── constants.ts # Configuration constants & shared utilities
│ ├── types.ts # TypeScript type definitions
│ ├── schemas/
│ │ ├── index.ts # Zod validation schemas for all tools
│ │ ├── projects.ts # Project-specific schemas
│ │ └── schemas.test.ts # Schema validation tests
│ ├── services/
│ │ ├── api-client.ts # FreeAgent API client (Axios)
│ │ ├── api-client.test.ts # API client tests
│ │ ├── formatter.ts # Response formatting utilities (incl. discount amount helper)
│ │ ├── formatter.test.ts # Formatter tests
│ │ ├── resolvers.ts # Shared resolvers (category / user / contact / bill hints → URLs)
│ │ ├── oauth-jwt.ts # JWT-based OAuth provider (Vercel)
│ │ └── freeagent-auth.ts # Token validation
│ └── tools/
│ ├── register.ts # Shared tool definitions, registration, ToolContext (elicitation)
│ ├── contacts.ts # Contact CRUD
│ ├── invoices.ts # Invoice management (incl. elicitation fallback)
│ ├── transition-invoice.ts # Invoice lifecycle transitions
│ ├── invoice-from-timeslips.ts # Intent bundle: draft an invoice from unbilled time
│ ├── estimates.ts # Estimates + transition_estimate
│ ├── bills.ts # Supplier bills
│ ├── recurring-invoices.ts # Recurring invoice templates (read-only)
│ ├── price-list-items.ts # Catalog items
│ ├── expenses.ts # Expense & mileage tracking
│ ├── log-expense.ts # Intent bundle: positive-amount expense logging
│ ├── timeslips.ts # Time tracking (incl. update_timeslip)
│ ├── bank-accounts.ts # Bank accounts & transactions
│ ├── bank-transactions.ts # Transaction explanations
│ ├── reconcile.ts # Intent bundle: reconcile a transaction in one call
│ ├── projects.ts # Project management
│ ├── tasks.ts # Task management
│ ├── categories.ts # Accounting categories
│ └── company.ts # Company info & users
├── api/
│ └── index.ts # Vercel serverless entry point
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI (lint, test, build)
├── eslint.config.js # ESLint flat config
├── vitest.config.ts # Vitest configuration
├── vercel.json # Vercel deployment config
├── package.json
└── tsconfig.json
CI
GitHub Actions runs on every push to main and on pull requests:
- Lint: ESLint with TypeScript rules
- Test: Vitest unit tests (no external API calls)
- Build: TypeScript compilation check
Rate Limiting
| Environment | Limit |
|---|---|
| Production | 15 requests / 60 seconds |
| Sandbox | 5 requests / 60 seconds |
The server returns clear error messages with retry-after timing when rate limited.
Error Handling
All tool handlers return structured errors via { isError: true, content: [...] } (never thrown exceptions). Error messages are designed for LLM consumption with actionable guidance:
| Status | Meaning |
|---|---|
| 401 | Token expired - refresh OAuth token |
| 403 | Insufficient permissions |
| 404 | Resource not found or deleted |
| 422 | Validation error with field-level details |
| 429 | Rate limited - retry after N seconds |
Security
- Access tokens are never logged or committed
- JWT tokens use HS256 signing with configurable secret
- PKCE is used for the OAuth authorization flow
- Strict Zod schemas reject unexpected input fields
- Bearer auth middleware protects all MCP endpoints
License
MIT
Links
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。