Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Works with

Claude CodeClaude DesktopCursorVS CodeClineCodex CLIOpenClaw+ any MCP client

Install to Claude Code

This server doesn't publish a one-line install command. Follow the setup in the source repository.

Summary

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.md

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, and invoice_from_timeslips collapse 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_invoice falls back to a form elicitation when contact is 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, openWorldHint on 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-count and Link headers
  • 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

  1. Install and build:
   bun install
   bun run build
  1. Set environment variables:
   export FREEAGENT_ACCESS_TOKEN="your_access_token"
   export FREEAGENT_USE_SANDBOX="true"  # optional
  1. 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 StreamableHTTPServerTransport in stateless mode (no sessions)
  • OAuth 2.0 with PKCE via JWT-encoded tokens (no database needed)
  • Handles POST (tool calls), GET (SSE streaming), and DELETE (returns 405 - stateless)
  • Set PRODUCTION_URL (or rely on VERCEL_PROJECT_PRODUCTION_URL) for stable production OAuth callback URLs. Preview OAuth uses the request host (or VERCEL_URL) so short per-deploy hosts match FreeAgent * wildcards.

Required env vars: FREEAGENT_CLIENT_ID, FREEAGENT_CLIENT_SECRET, JWT_SECRET (stable secret required on Vercel so OAuth JWTs verify across serverless instances)

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

See related servers & alternatives →

Related MCP servers

Browse all →

Related guides

Hand-picked reading to help you choose and use Cloud & DevOps servers.