Content
# @crowdform/freeagent-mcp
An MCP server for the [FreeAgent](https://www.freeagent.com) accounting API, so Claude can
work with your accounts: browse invoices, bills, expenses, contacts and bank transactions,
and help you **reconcile** unexplained bank activity.
Built against the [FreeAgent API v2 docs](https://dev.freeagent.com/docs/introduction)
(no OpenAPI spec exists — the API surface is indexed by hand under `docs/api/`).
## Setup
Zero configuration — default OAuth app credentials are baked into the package, so install
and connect:
```sh
claude mcp add freeagent -- npx -y @crowdform/freeagent-mcp
```
Or for Claude Desktop, add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"freeagent": { "command": "npx", "args": ["-y", "@crowdform/freeagent-mcp"] }
}
}
```
Then ask Claude to **connect to FreeAgent** — it runs the `connect_freeagent` tool, which
opens your browser to FreeAgent's approval page. The baked-in credentials only identify the
app asking for access; nothing can touch your account until you click Approve on FreeAgent's
own login page.
## How auth & the token file work
Your login lives in **`~/.freeagent-tokens.json`** (move it with `FREEAGENT_TOKEN_PATH`).
When you approve access, the OAuth tokens **and the organisation they belong to** (company
name, subdomain, currency) are saved there. On every startup the server reads that file and
announces which organisation it is logged into, and `check_auth_status` reports it too — so
Claude always knows whose books it's working on. To switch to a different FreeAgent account,
run `connect_freeagent` with `force=true` (or delete the token file) and approve as the
other account.
Tokens auto-refresh; you only need to authorize once (or again if the refresh token is revoked).
### Using your own OAuth app (optional)
The baked-in defaults are used unless you override them: create an app at
[dev.freeagent.com](https://dev.freeagent.com) (My Apps), add
`http://localhost:8462/callback` to its **OAuth redirect URIs**, and set
`FREEAGENT_CLIENT_ID` / `FREEAGENT_CLIENT_SECRET` in the environment (or a `.env` next to
`package.json` when running from a checkout).
Set `FREEAGENT_SANDBOX=true` to point at the sandbox — this requires your own sandbox app;
the baked-in app is production-only.
### Authorizing from a terminal instead
From a checkout of this repo, `npm run auth` runs the same browser flow without an MCP
session and saves tokens to the same place.
### Authorizing without a localhost callback
If you can't (or don't want to) register the localhost redirect URI, get a refresh token any
other way — e.g. the [Google OAuth Playground](https://developers.google.com/oauthplayground)
(gear icon → "Use your own OAuth credentials", authorization endpoint
`https://api.freeagent.com/v2/approve_app`, token endpoint
`https://api.freeagent.com/v2/token_endpoint`) — then import it:
```sh
npm run auth -- --refresh-token <refresh_token>
```
This exchanges the refresh token for an access token, verifies it against the API, and saves
both to the token file. FreeAgent refresh tokens are long-lived (valid until you revoke the
app's access), and the server rotates/persists them automatically on every refresh — so this
is a one-time step.
## What it can do
- **Company & reference data** — company info, users, categories (with nominal codes), contacts
- **Sales** — list/get/create invoices, status transitions, credit notes, estimates
- **Purchases** — bills and expenses
- **Banking** — bank accounts, bank transactions (filter unexplained/manual/etc.)
- **Reconciliation** — create/update/delete bank transaction explanations (link to invoices,
bills, transfers, or categorised money in/out), plus a matching helper that pairs
unexplained transactions with open invoices/bills by amount, date and reference
- **Reports** — profit & loss, balance sheet, trial balance, VAT returns, general-ledger transactions
## Notes
- FreeAgent identifies resources by **URL** (e.g. `https://api.freeagent.com/v2/invoices/123`).
Tools accept either the full URL or the bare numeric id.
- List tools fetch up to 4 pages of 100 items and tell you when results were truncated.
- Rate limits (120/min) are handled with automatic backoff on 429s.
- The connected organisation (name, subdomain, currency) is saved alongside the tokens at
authorization time, announced in the server's MCP instructions at startup, and returned by
`check_auth_status` — so the assistant always knows whose books it is working on.
## License & disclaimer
MIT — see [LICENSE](LICENSE). This is an unofficial integration, not affiliated with or
endorsed by FreeAgent Central Ltd. "FreeAgent" is a trademark of FreeAgent Central Ltd; all
rights in the FreeAgent API and any data accessed through it remain with FreeAgent and the
respective account holders. Your use of the API via this software is subject to FreeAgent's
own terms.