README
¶
FreeAgent MCP Server
A local Model Context Protocol server that gives Hermes Agent broad access to a FreeAgent company account. It uses the official Go MCP SDK, FreeAgent OAuth 2.0, and the FreeAgent v2 API.
[!IMPORTANT] This is an independent, unofficial integration maintained by Mentioum Technologies. It is not affiliated with, endorsed by, or supported by FreeAgent. FreeAgent is the provider of the accounting service and API.
The server has focused tools for the high-frequency accounting workflows—expenses, mileage, receipts, bank payments, and evidence—plus guarded generic CRUD tools that cover the rest of the documented FreeAgent API without requiring a new server release for every endpoint.
About the maintainers
freeagent-mcp was built by serial technical founder Jeremy Hindle because he needed it to manage his own company accounting. You can learn more about Jeremy at mentioum.net.
What Hermes can do
- Submit ordinary, travel, subsistence, and other out-of-pocket expenses.
- Submit car, motorcycle, and bicycle mileage claims using FreeAgent's date-specific mileage settings.
- Attach PNG, JPEG, GIF, or PDF evidence (up to FreeAgent's 5 MB limit) while creating an expense or bank explanation.
- Add or replace evidence on an existing expense or bank-transaction explanation.
- Find unexplained bank payments and receipts, then explain them against categories, invoices, bills, users, projects, transfers, or other FreeAgent-supported types.
- Upload OFX, QIF, or FreeAgent-supported CSV bank statement files.
- Read and manage contacts, projects, invoices, bills, estimates, timeslips, tasks, notes, properties, stock, journal sets, recurring invoices, and other v2 resources through generic tools.
- Query reports and tax/accounting endpoints available to the authorizing FreeAgent user.
The connected FreeAgent user's role and access level still apply. FreeAgent may reject changes in locked periods or records that are not editable.
Tools
| Tool | Purpose |
|---|---|
freeagent_connection_status |
Verify OAuth and show the connected company/user |
freeagent_list |
Query any v2 collection or report |
freeagent_get |
Fetch any single v2 resource |
freeagent_create |
Create any documented v2 resource |
freeagent_update |
Update any documented v2 resource |
freeagent_delete |
Delete a resource when FreeAgent permits it |
freeagent_submit_expense |
Submit an expense with optional receipt evidence |
freeagent_submit_mileage |
Submit mileage with optional evidence |
freeagent_attach_expense_evidence |
Attach/replace evidence on an expense |
freeagent_get_mileage_settings |
Get rates and date-valid engine choices |
freeagent_list_bank_transactions |
Find unexplained/explained bank activity |
freeagent_upload_bank_statement |
Upload an OFX, QIF, or supported CSV statement |
freeagent_explain_bank_transaction |
Explain a payment/receipt with optional evidence |
freeagent_attach_bank_evidence |
Attach/replace evidence on a bank explanation |
1. Build
Go 1.25 or newer is required by the current official MCP Go SDK. Linux, macOS, and Windows are tested in CI; the Makefile build/install helpers require a POSIX shell, while Windows users can build with go build -o freeagent-mcp.exe ./cmd/freeagent-mcp.
git clone --branch v1.0.0 --depth 1 https://github.com/Mentioum-Technologies/freeagent-mcp.git
cd freeagent-mcp
make install
The binary is built at bin/freeagent-mcp and installed to ~/.local/bin/freeagent-mcp.
2. Create a FreeAgent API app
-
Sign in to the FreeAgent Developer Dashboard.
-
Create an app and set its redirect URI to exactly:
http://127.0.0.1:8484/callback -
Copy the client ID and client secret.
For initial testing, create the app/account in FreeAgent's sandbox and set FREEAGENT_SANDBOX=true during both authorization and normal server use.
3. Authorize the account
export FREEAGENT_CLIENT_ID='your-client-id'
export FREEAGENT_CLIENT_SECRET='your-client-secret'
~/.local/bin/freeagent-mcp auth
The command opens FreeAgent in the browser, receives the localhost callback, removes the authorization code from browser history with a query-free confirmation redirect, and saves the access/refresh token to ~/.config/freeagent-mcp/token.json with owner-only file and directory permissions. FreeAgent rotates refresh tokens; the server saves the new token atomically.
Keep FREEAGENT_CLIENT_ID and FREEAGENT_CLIENT_SECRET available whenever the MCP server runs, because they are required to refresh the one-hour access token. Do not commit them to this repository.
4. Add it to Hermes Agent
Store the OAuth application credentials in Hermes' secret environment file:
# ~/.hermes/.env
FREEAGENT_CLIENT_ID=your-client-id
FREEAGENT_CLIENT_SECRET=your-client-secret
# FREEAGENT_SANDBOX=true
Then register the stdio server:
hermes mcp add freeagent \
--command "$HOME/.local/bin/freeagent-mcp" \
--args serve
Hermes intentionally gives stdio MCP subprocesses a filtered environment. Variables merely present in ~/.hermes/.env are not passed through automatically. Explicitly grant this server the two credentials using runtime placeholders:
hermes config set mcp_servers.freeagent.env.FREEAGENT_CLIENT_ID '${FREEAGENT_CLIENT_ID}'
hermes config set mcp_servers.freeagent.env.FREEAGENT_CLIENT_SECRET '${FREEAGENT_CLIENT_SECRET}'
The resulting ~/.hermes/config.yaml entry should be:
mcp_servers:
freeagent:
command: "/home/your-user/.local/bin/freeagent-mcp"
args: ["serve"]
enabled: true
env:
FREEAGENT_CLIENT_ID: ${FREEAGENT_CLIENT_ID}
FREEAGENT_CLIENT_SECRET: ${FREEAGENT_CLIENT_SECRET}
The placeholders are resolved from the active Hermes profile's .env when the MCP server starts. This keeps secrets out of config.yaml while granting the subprocess only the credentials it needs. Do not replace this with a wrapper that sources the whole .env; that would expose unrelated credentials to the MCP process.
Reload and verify the connection:
/reload-mcp
hermes mcp test freeagent
In a Hermes conversation, call freeagent_connection_status and confirm the expected company, user, and production/sandbox mode before accessing accounting records. MCP-backed tools are displayed internally with names such as mcp__freeagent__freeagent_connection_status; the segments identify the MCP transport, configured server, and server-native tool.
If sandbox mode is required, also grant it explicitly:
env:
FREEAGENT_CLIENT_ID: ${FREEAGENT_CLIENT_ID}
FREEAGENT_CLIENT_SECRET: ${FREEAGENT_CLIENT_SECRET}
FREEAGENT_SANDBOX: ${FREEAGENT_SANDBOX}
Do not enable supports_parallel_tool_calls for this server: several tools mutate shared accounting records. See Hermes Agent setup and troubleshooting for the complete configuration, security model, profiles, and common failure modes.
Suggested Hermes workflows
Submit a travel expense with a receipt
Ask Hermes to:
- Call
freeagent_listforusersandcategoriesto resolve the claimant and correct travel category. - Call
freeagent_submit_expensewith the date, description, negative gross value, category, and the local receipt path. - Read the returned expense and report its FreeAgent URL.
Local path uploads are disabled until FREEAGENT_FILE_ROOTS grants one or more dedicated directories. Alternatively, send evidence with data_base64, which does not require local-file access.
FreeAgent's sign convention matters: a normal expense owed to the claimant uses a negative gross_value; a refund due from the claimant uses a positive value.
Submit mileage
Ask Hermes to call freeagent_get_mileage_settings first, particularly for electric vehicles. The engine labels valid from September 2025 differ from older labels. It can then call freeagent_submit_mileage with the route/business purpose, miles, vehicle, and reclaim choice.
Explain a payment and attach evidence
Ask Hermes to:
- List
bank_accounts. - Call
freeagent_list_bank_transactionswithview: unexplained. - Fetch the selected transaction and list
categories. - Call
freeagent_explain_bank_transaction, including the receipt/invoice path asevidence.path.
FreeAgent supports only one attachment object on an expense or bank explanation. Attaching new evidence to an existing record may replace its current attachment.
Generic API tools
Generic paths are relative to /v2. Request bodies must include the root key required by FreeAgent's documentation. For example, creating a contact uses:
{
"path": "contacts",
"body": {
"contact": {
"first_name": "Ada",
"last_name": "Lovelace",
"organisation_name": "Analytical Engines Ltd"
}
}
}
Full FreeAgent resource URLs returned by the API are accepted, but URLs on other hosts and paths outside /v2 are rejected.
Configuration
| Environment variable | Default | Description |
|---|---|---|
FREEAGENT_CLIENT_ID |
— | OAuth app client ID; needed for auth and refresh |
FREEAGENT_CLIENT_SECRET |
— | OAuth app secret; needed for auth and refresh |
FREEAGENT_ACCESS_TOKEN |
token file | Optional direct access token, useful for short tests |
FREEAGENT_REFRESH_TOKEN |
token file | Optional refresh-token override |
FREEAGENT_TOKEN_FILE |
~/.config/freeagent-mcp/token.json |
Secure token store path |
FREEAGENT_FILE_ROOTS |
— (path uploads disabled) | OS path-list of directories from which evidence and statements may be read (: on Unix/macOS, ; on Windows) |
FREEAGENT_REDIRECT_URI |
http://127.0.0.1:8484/callback |
Must exactly match the developer app |
FREEAGENT_SANDBOX |
false |
Use api.sandbox.freeagent.com |
FREEAGENT_API_BASE |
production/sandbox v2 URL | Optional exact FreeAgent production or sandbox API URL; arbitrary and localhost origins are rejected from the process environment |
FREEAGENT_MCP_TRANSPORT |
stdio |
stdio or http |
FREEAGENT_MCP_LISTEN |
127.0.0.1:8080 |
HTTP listen address |
Stdio is recommended for Hermes. HTTP mode exposes Streamable HTTP at http://127.0.0.1:8080/mcp and a health check at /healthz. For safety, the binary refuses non-loopback HTTP binds; put a TLS-authenticated reverse proxy or secure tunnel in front if remote access is required.
Development and verification
make check
This verifies formatting and module-file cleanliness, runs go vet, executes race-enabled unit tests against fake FreeAgent APIs, verifies attachment limits/types and token-file permissions, and performs an in-memory MCP handshake/tool-discovery test. CI additionally runs govulncheck and tests Windows.
Release changes are recorded in CHANGELOG.md. Maintainers should release only from a clean, reviewed commit that passes CI; generated files under bin/ are local build artifacts and must not be committed. Verify the built binary with freeagent-mcp version before creating a release tag.
The implementation follows FreeAgent's documented OAuth flow, expense and mileage API, bank transaction explanations, and rate limits.
Security and privacy
OAuth credentials and tokens are never embedded in this repository or its binaries. Tokens are stored locally with owner-only permissions, and accounting data is sent directly between the local MCP process and the fixed production/sandbox FreeAgent origins. Arbitrary remote API origins are rejected. Local path reads are disabled by default and, when enabled, use rooted, bounded, regular-file reads that reject traversal and symlink escapes; evidence types are verified from file signatures rather than caller metadata. See SECURITY.md for vulnerability reporting and deployment guidance.