Skip to main content
Glama
OxygenBubbles

FreeAgent MCP Server

FreeAgent MCP Server

A Model Context Protocol server for FreeAgent accounting. Gives Claude (or any MCP client) the ability to reconcile bank transactions with receipts, claim expenses and mileage, raise and chase invoices, record supplier bills, log time against projects, and read the company's financial position.

What access this server requires

FreeAgent

The FreeAgent OAuth credentials grant full access to the connected FreeAgent account. This server uses that access to:

Action

Tools that use it

Read bank accounts

freeagent_list_bank_accounts

Read bank transactions and explanations

freeagent_list_transactions

Update transaction explanations (category, description, project, rebilling, VAT, approval, attachments)

freeagent_explain_transaction

Read, create, amend and delete expense claims

freeagent_list_expenses, freeagent_create_expense, freeagent_create_mileage_expense, freeagent_update_expense, freeagent_delete_expense

Read the chart of accounts

freeagent_list_categories

Read, create, amend and delete projects

freeagent_list_projects, freeagent_create_project, freeagent_update_project, freeagent_delete_project

Read, create, amend and delete contacts

freeagent_list_contacts, freeagent_create_contact, freeagent_update_contact, freeagent_delete_contact

Read, raise, edit and change the status of invoices

freeagent_list_invoices, freeagent_get_invoice, freeagent_create_invoice, freeagent_update_invoice, freeagent_update_invoice_status

Read, record and amend supplier bills

freeagent_list_bills, freeagent_get_bill, freeagent_create_bill, freeagent_update_bill

Read, log and amend time against project tasks

freeagent_list_tasks, freeagent_create_task, freeagent_update_task, freeagent_list_timeslips, freeagent_create_timeslip, freeagent_update_timeslip

Read accounting reports

freeagent_profit_and_loss, freeagent_trial_balance, freeagent_aged_debtors, freeagent_aged_creditors, freeagent_tax_timeline, freeagent_company_summary

Delete expenses, invoices, bills, contacts, projects, tasks and timeslips

freeagent_delete_expense, freeagent_delete_invoice, freeagent_delete_bill, freeagent_delete_contact, freeagent_delete_project, freeagent_delete_task, freeagent_delete_timeslip

FreeAgent does not offer granular OAuth scopes — authorising an app grants access to all of the above.

Destructive operations. The delete tools are flagged destructiveHint: true so your MCP client can prompt before running them, as is freeagent_update_invoice_status (its mark_as_cancelled transition voids an issued invoice). The three whose loss is unrecoverable — freeagent_delete_expense, freeagent_delete_contact and freeagent_delete_project — additionally require confirm: true, so a client that auto-approves tool calls still cannot trigger them by accident. The server never deletes bank transactions, and never emails anything to your clients — status transitions change status only.

Outbound fetches. freeagent_explain_transaction, freeagent_create_expense, freeagent_update_expense, freeagent_create_bill and freeagent_update_bill each accept a fileUrl to download a receipt or invoice. That URL is treated as untrusted input: only http/https are allowed, hosts resolving to loopback, link-local, or private addresses are refused (on the initial request and on every redirect), and downloads are capped at 10 MB.

Local file reads. Those same tools accept a filePath, and the server reads that file from the host it runs on. The path must be absolute, and symlinks are resolved before the check. Over stdio the server runs as you, so this is no more access than the client already has. In HTTP mode the caller is remote, so local paths are refused outright unless you set FREEAGENT_ATTACHMENT_ROOTS to the directories that may be read (colon-separated); anything outside them is refused. Set it in stdio mode too if you want to bound what a prompt-injected model can attach.

Truncation. List tools page through results and report mayHaveMore; when true, any total they return covers only the records fetched and is named totalOutstandingForReturned. The freeagent_aged_debtors and freeagent_aged_creditors reports page to exhaustion and return complete: true — treat complete: false as an incomplete figure. Records whose due date is missing or unparseable are counted in a separate unknown_due_date bucket rather than being assumed not yet due.

Email and file sources (external — not provided by this server)

This server has no email tools. For receipt/invoice search to work automatically, connect one or more of the following MCP servers alongside this one:

  • Gmail (e.g. mcp__claude_ai_Gmail) — personal email

  • Microsoft 365 / Outlook (e.g. mcp__claude_ai_microsoft-365) — business email

When both are connected, Claude will search all of them automatically for matching receipts before asking you to provide a file manually.


Related MCP server: freee MCP Server

Tools

Banking and expenses

Tool

Description

freeagent_list_bank_accounts

List all bank accounts and their IDs

freeagent_list_transactions

List transactions (unexplained / explained / all / marked_for_review) with date filters

freeagent_explain_transaction

Update, approve, rebill or attach a receipt to a transaction explanation

freeagent_list_categories

List the full chart of accounts — all four category groups

freeagent_list_expenses

List expense claims by date or project, with unbilledOnly for costs queued to bill on and untaggedRebillOnly for project-tagged costs that will never be billed

freeagent_create_expense

Create an expense claim with optional receipt (local path, URL or base64), project tag with rebill type/factor, EC VAT status and bank-transaction auto-matching

freeagent_update_expense

Update an existing expense — attach or replace the receipt, set the rebill treatment, retag project/category, correct date, amount or VAT

freeagent_create_mileage_expense

Create a mileage claim with engine type/size for fuel VAT, optionally rebilled to a project; the rate comes from the account's own mileage settings

freeagent_delete_expense

Delete an expense filed in error (needs confirm: true)

Contacts, invoicing and bills

Tool

Description

freeagent_list_contacts

List clients and suppliers, with an optional name/email filter

freeagent_create_contact

Create a client or supplier, with VAT registration number and default payment terms

freeagent_update_contact

Update a contact, add its VAT number, or hide it (status: "Hidden")

freeagent_delete_contact

Delete a contact (needs confirm: true)

freeagent_list_invoices

List invoices by view (overdue, open_or_overdue, draft, paid…) with the total outstanding

freeagent_get_invoice

Fetch one invoice in full, including line items

freeagent_create_invoice

Raise an invoice with line items and EC VAT status — always created as a draft

freeagent_update_invoice

Edit a draft invoice — dates, project, VAT status, discount, and add/edit/remove line items

freeagent_update_invoice_status

Mark an invoice as sent, draft, scheduled or cancelled (no email is sent)

freeagent_delete_invoice

Delete an invoice

freeagent_list_bills

List supplier bills with the total outstanding

freeagent_get_bill

Fetch one bill in full, including line items and their URLs (needed to edit lines)

freeagent_create_bill

Record a supplier bill, with optional invoice attachment (local path, URL or base64), EC VAT status, project allocation and rebill treatment

freeagent_update_bill

Update a bill — reference, dates, VAT status, project, rebill treatment, attachment and line items

freeagent_delete_bill

Delete a bill

Time tracking

Tool

Description

freeagent_list_tasks

List project tasks (time is always logged against a task)

freeagent_create_task

Create a project task with its billing rate

freeagent_update_task

Rename a task, change its billing rate, or close it (status: "Completed")

freeagent_delete_task

Delete a task with no time logged against it

freeagent_list_timeslips

List logged time for a date range, with totals per project; view: "unbilled" finds uninvoiced work

freeagent_create_timeslip

Log time against a project task

freeagent_update_timeslip

Correct a timeslip's hours, date, task or comment

freeagent_delete_timeslip

Delete a timeslip

Projects

Tool

Description

freeagent_list_projects

List projects, for tagging expenses, invoices, bills and time

freeagent_create_project

Create a project against a client contact — only contact and name are required

freeagent_update_project

Rename, rebudget, change billing rate or close a project

freeagent_delete_project

Delete a project with nothing booked against it (needs confirm: true)

Reporting

Tool

Description

freeagent_profit_and_loss

Income, expenses, operating profit, corporation tax estimate and retained profit

freeagent_trial_balance

Balance on every nominal account

freeagent_aged_debtors

Unpaid customer invoices bucketed by age (not yet due, 1–30, 31–60, 61–90, 90+ days)

freeagent_aged_creditors

Unpaid supplier bills bucketed by age

freeagent_tax_timeline

Upcoming VAT, corporation tax and Companies House deadlines with amounts due

freeagent_company_summary

Company details, VAT registration and accounting year end


Prerequisites

FreeAgent OAuth credentials

  1. Log in to FreeAgent → Settings → Developer API.

  2. Create an OAuth application. Set the redirect URI to http://localhost:8080/callback.

  3. Note your Client ID and Client Secret.

  4. Run the bundled auth command to complete the OAuth flow and save a refresh token to .mcp.json automatically:

npx @oxygenbubbles/freeagent-mcp-server auth

The command prompts for your Client ID and Client Secret, opens the FreeAgent authorization page in your browser, listens for the callback, exchanges the code for a long-lived refresh token, and writes everything to .mcp.json in the current directory. If .mcp.json already exists, it updates just the freeagent entry.


Installation

git clone https://github.com/OxygenBubbles/freeagent-mcp-server.git
cd freeagent-mcp-server
npm install
npm run build

Configuration

All settings are read from environment variables.

Required

Variable

Description

FREEAGENT_CLIENT_ID

OAuth client ID

FREEAGENT_CLIENT_SECRET

OAuth client secret

FREEAGENT_REFRESH_TOKEN

Long-lived refresh token

Optional

Variable

Description

VENDOR_CATEGORIES

JSON object extending the built-in vendor → category mapping (see below)

MILEAGE_CATEGORY_URL

FreeAgent category URL for mileage expenses (default /v2/categories/249, the standard Mileage category)

MILEAGE_RATE_PENCE

Fallback pence-per-mile rate for the estimate, used only when FreeAgent's own mileage settings cannot be read

HMRC_RATE_HIGH_PENCE

HMRC high-band rate in pence, used as a last-resort fallback (default 45)

HMRC_RATE_LOW_PENCE

HMRC low-band rate in pence, used as a last-resort fallback (default 25)

HMRC_THRESHOLD_MILES

Miles per tax year before the low band kicks in (default 10000)

ORS_API_KEY

OpenRouteService API key for drive-distance lookups

GOOGLE_MAPS_API_KEY

Google Maps API key for drive-distance lookups (alternative to ORS)

PORT

If set, serves over HTTP on this port instead of stdio

FREEAGENT_ATTACHMENT_ROOTS

Colon-separated directories that filePath attachments may be read from. Required for local paths in HTTP mode; optional (and recommended) over stdio

AUTH_TOKEN

Bearer token required on every HTTP request. Strongly recommended whenever PORT is set

FREEAGENT_DEBUG

Set to 1 to log every request and error response to stderr. Tokens, credentials and file payloads are redacted

Built-in vendor → category mappings

The server ships with mappings for common vendors, using FreeAgent's standard UK nominal codes:

  • Web Hosting (268) — IONOS, AWS, Netlify, Vercel, Heroku, DigitalOcean, Cloudflare

  • Computer Software (269) — OpenAI, Anthropic, GitHub, Stripe, Google, Microsoft, Zoom, Notion, Dropbox, Slack, Adobe, Fastmail, Mailchimp

  • Accommodation and Meals (285) — Booking.com, Hotels.com, Premier Inn, Travelodge, Airbnb

  • Travel (365) — Trainline, LNER, Uber

Check these against your own chart of accounts with freeagent_list_categories — nominal codes can be customised per account. Override or extend via VENDOR_CATEGORIES:

VENDOR_CATEGORIES='{"ACME CORP":"/v2/categories/285","NETFLIX":"/v2/categories/269"}'

Claude Desktop setup

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "freeagent": {
      "command": "node",
      "args": ["/path/to/freeagent-mcp-server/dist/index.js"],
      "env": {
        "FREEAGENT_CLIENT_ID": "...",
        "FREEAGENT_CLIENT_SECRET": "...",
        "FREEAGENT_REFRESH_TOKEN": "..."
      }
    }
  }
}

Usage examples

List my unexplained Starling transactions for April 2026

Approve explanation 12345678 and attach the receipt at ~/Downloads/invoice.pdf

Create an expense for the £22.80 IONOS charge on 3 April, rebilled to the Example Client project at cost — the receipt is at ~/Desktop/ionos.png

That IONOS expense should be Reverse Charge, not UK/Non-EC — fix it

Log 24 miles for a client visit from the office to a customer site on 10 April

Add a line to draft invoice 4471 for 2 days' consultancy at £650

Which April expenses are tagged to a project but not set to rebill?

Show me everything queued to bill on to Example Client that isn't on an invoice yet

Mileage rates

Mileage is a special FreeAgent category: you submit the miles and vehicle type, and FreeAgent calculates the claim value from the mileage rate configured on the account. That figure is what appears in your accounts and HMRC reporting, so the server does not attempt to override it.

The estimate returned alongside the filed amount uses that same rate: the server reads GET /v2/expenses/mileage_settings and applies the band published for the journey's date and vehicle. The response records where the rate came from in estimateSource:

estimateSource

Meaning

freeagent_mileage_settings

The account's own published rate — the normal case

argument

A ratePence you passed explicitly, which always wins

MILEAGE_RATE_PENCE

Settings could not be read; the environment variable was used

hmrc_defaults

Settings could not be read and no override was set; the built-in HMRC bands were used

The last two are fallbacks, and the response says so in notes. When the estimate and the filed amount still differ, that is worth a look:

FreeAgent filed £46.20 using the mileage rate configured on the account; the estimate from 84 miles @ 45p/mile (FreeAgent mileage settings) was £37.80.

HMRC's approved rates are 45p/mile for the first 10,000 business miles in the tax year and 25p above it, and anything paid above the approved rate is a taxable benefit.

To reclaim the VAT on the fuel element, pass engineType and engineSize (and haveVatReceipt) — FreeAgent cannot calculate it without them.


Development

npm run dev        # watch mode (tsx)
npm run build      # compile TypeScript → dist/
npm start          # run compiled server
npm test           # run unit tests once
npm run test:watch # watch mode for tests

Claude Code setup

Create .mcp.json in your project directory (or ~/.mcp.json for global access):

{
  "mcpServers": {
    "freeagent": {
      "command": "node",
      "args": ["/path/to/freeagent-mcp-server/dist/index.js"],
      "env": {
        "FREEAGENT_CLIENT_ID": "...",
        "FREEAGENT_CLIENT_SECRET": "...",
        "FREEAGENT_REFRESH_TOKEN": "..."
      }
    }
  }
}

HTTP mode

Set PORT to run as an HTTP server (for webhooks, iPhone Shortcuts, Power Automate):

PORT=3000 AUTH_TOKEN=a-long-random-string node dist/index.js

Always set AUTH_TOKEN when exposing HTTP mode — every request must include Authorization: Bearer <AUTH_TOKEN> or it is rejected with 401. Without AUTH_TOKEN the server starts anyway but prints a warning to stderr and accepts all requests; only do that on a trusted loopback interface.


Security

  • Credentials are environment variables, never in code

  • FreeAgent tokens are cached in memory and refreshed automatically

  • Transactions are never approved without a confirmed receipt or explicit instruction

  • The server never creates new categories — only selects from existing ones

  • Receipt URLs are fetched through an SSRF guard: the address validated is the address dialled, every redirect hop is re-checked, proxies are bypassed and downloads are size-capped

  • Local receipt paths must be absolute and are resolved through symlinks before use; in HTTP mode they are refused unless FREEAGENT_ATTACHMENT_ROOTS names the directories that may be read

  • The three deletes whose loss is unrecoverable — expenses, contacts and projects — require confirm: true in addition to the client's own prompt

  • .mcp.json is excluded from git via .gitignore


Licence

MIT

Available Tools

28 tools
freeagent_aged_creditorsA
Read-only

Aged creditors — unpaid supplier bills bucketed by how overdue they are. Shows what the company owes and for how long.

ParametersJSON Schema
NameRequiredDescriptionDefault
asAtNoAge against this date YYYY-MM-DD (default: today)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context: it filters to unpaid supplier bills and organizes them into overdue buckets, which explains the report's structure. It does not contradict annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences that are front-loaded with the key term 'Aged creditors' and immediately explain what the report does. No filler or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, read-only report with one optional parameter and no output schema, the description provides sufficient context about what the tool does and what it shows. It doesn't detail the exact response structure but the mention of 'bucketed' hints at the output. Slightly more detail about the asAt parameter could improve it, but it's not necessary.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the only parameter (asAt) is fully described with format and default value. The tool description does not add any extra parameter information, which is acceptable since the schema carries the burden. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: it shows unpaid supplier bills bucketed by how overdue they are. This distinguishes it from the sibling tool freeagent_aged_debtors (which presumably covers customer invoices) by explicitly mentioning 'supplier bills' and 'what the company owes.'

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied rather than explicit. The description indicates this is for viewing supplier-related aged balances, which implies using it when you need creditor aging info, but it does not directly reference alternatives or state when not to use it. No exclusions or alternative tool names are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_aged_debtorsA
Read-only

Aged debtors — unpaid customer invoices bucketed by how overdue they are (not yet due, 1-30, 31-60, 61-90, 90+ days). Shows who owes what and for how long.

ParametersJSON Schema
NameRequiredDescriptionDefault
asAtNoAge against this date YYYY-MM-DD (default: today)

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds clarity by defining the aging buckets and output focus, but it doesn't disclose additional behavioral context such as how the aging is calculated or whether all customers are included. The description does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the key concept ('Aged debtors') and efficiently elaborates with bucket details. Every word contributes meaning; there is no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only report with one optional parameter, the description adequately conveys the report's content and purpose. It clearly explains the output (aging buckets and who owes what) even without an output schema. Slight gap: it doesn't mention the optional 'asAt' parameter in the description, but the schema covers that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides 100% coverage for the only parameter (asAt) with a clear date format and default. The description adds no extra parameter-specific detail, but the baseline of 3 applies because the schema fully documents the parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: it lists unpaid customer invoices bucketed by aging periods. It explicitly defines the resource ('aged debtors') and the action ('shows who owes what and for how long'), and the name + description naturally distinguish it from the sibling 'freeagent_aged_creditors'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool (when analyzing overdue receivables) but does not explicitly state when-not-to or mention alternatives like freeagent_aged_creditors. It gives a clear context but lacks exclusions or comparative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_company_summaryA
Read-only

FreeAgent company details — name, type, company registration number, VAT registration status, accounting year end and currency.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is known. The description adds value by specifying the exact set of returned fields, which is useful because there is no output schema. It does not contradict annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with an em dash to list contents. Every word earns its place, and there is no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only tool with no output schema, the description fully communicates what the tool returns. The listed fields are sufficient for an agent to know what to expect. No additional context is required.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

This tool has zero parameters, and the schema is complete with no properties. The description correctly avoids inventing parameters. With 0 parameters, the baseline is 4, and no further parameter explanation is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource (FreeAgent company details) and enumerates the specific fields returned (name, type, registration number, VAT status, year end, currency). This distinguishes it from sibling tools that deal with contacts, invoices, bills, and other specific entities.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit usage guidelines or alternative tools are mentioned. The purpose is clear enough that an agent can infer when to use it (when company-level details are needed), but it does not state exclusions or compare to siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_create_billA

Record a supplier bill (an invoice the company has received and owes). Each line needs a spending category and a value including tax.

RECEIPTS: before asking the user for the PDF, search connected email tools (Gmail, Outlook/M365) for the supplier invoice and pass it as fileBase64 + fileName.

ParametersJSON Schema
NameRequiredDescriptionDefault
dueOnYesPayment due date YYYY-MM-DD
itemsYesBill line items — at least one, at most 40
contactYesSupplier the bill is from — create one with freeagent_create_contact
datedOnYesBill date YYYY-MM-DD
projectNoProject to allocate this bill to
currencyNoISO 4217 currency (default: company currency)
fileNameNoFile name (e.g. 'invoice.pdf')
referenceYesSupplier's invoice reference (e.g. 'INV-2049')
fileBase64NoBase64-encoded supplier invoice (PDF, PNG, JPEG)
rebillTypeNoHow to rebill this to the client
contentTypeNoMIME type. Inferred from fileName if omitted.
rebillFactorNoMarkup percentage or fixed price — required for markup/price

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description says 'Record', which appropriately signals a state-changing operation and matches the annotations. However, it does not disclose side effects beyond creation, such as whether duplicate calls create duplicate bills, or whether special permissions are required. Annotations cover read-only/destructive/idempotent hints, but the description adds little independent behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, front-loaded with the core purpose, and every sentence contributes either to tool selection or to an efficient workflow. The RECEIPTS note is prominent without being verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a table with 12 parameters, the description plus fully covered schema is enough for an agent to construct a valid call. It does not explain return values, but there is no output schema and create-tool output is not usually self-serve. A small gap is not explicitly stating what to do if no email match is found, though it is reasonably implied.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by emphasizing that every line requires a category and a value including tax, and it explains how fileBase64 and fileName should be supplied when a matching invoice is found in email tools. This is actionable semantics beyond the raw schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action and resource: 'Record a supplier bill', with the parenthetical 'an invoice the company has received and owes' removing ambiguity. This clearly separates the tool from invoice creation for customers and from expense recording without needing to inspect the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context for when to use the tool: recording supplier bills. The RECEIPTS section adds a concrete workflow instruction by telling the agent to search Gmail/Outlook for the supplier invoice before asking the user for a PDF. It does not explicitly name alternative tools or exclusion cases, but the contextual cue is strong enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_create_contactA

Create a contact in FreeAgent — a client to invoice or a supplier to record bills against. Supply either an organisation name or a first/last name (or both).

ParametersJSON Schema
NameRequiredDescriptionDefault
townNoTown or city
emailNoContact email address
regionNoCounty, region or state
countryNoCountry (e.g. 'United Kingdom')
address1NoFirst line of the address
address2NoSecond line of the address
lastNameNoContact last name
postcodeNoPostcode or ZIP
firstNameNoContact first name
phoneNumberNoContact phone number
chargeSalesTaxNoWhether to charge sales tax to this contact (default: Auto)
organisationNameNoCompany name (e.g. 'Example Client Ltd')
contactNameOnInvoicesNoShow the person's name rather than the organisation on invoices

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false, which adequately signals that this persists a new record and is not idempotent. The description adds the practical constraint about naming, but doesn't disclose duplicate behavior, permissions, or response shape. With the annotations in place, this is acceptable but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no filler. The subject and resource are front-loaded, and the sentence sentence explains both the use cases and the most important optional-field constraint. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a straightforward create operation with 13 optional params, the description covers the only non-obvious constraint (the naming rule) and leaves the rest to the full parameter schemas. The lack of an output schema and response details means the agent can't predict the exact returned object, but the description is still sufficient for selecting and invoking the tool correctly in most cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 13 parameters already have descriptions in the schema, so the baseline is 3. The description improves on that by clarifying the business grouping: either organisationName or firstName / lastName must be supplied (or both), and the contact is a client or supplier. This is semantic context not present in the parameter schemas.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the exact verb and resource ('Create a contact in FreeAgent') and explains why the contact is being created — a client to invoice or a supplier to record bills against. This distinguishes it cleanly from sibling tools like freeagent_create_invoice or freeagent_create_expense.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

By identifying the two business contexts that call for this tool — invoicing a client or recording bills against a supplier — the description gives an agent a clear trigger. It doesn't explicitly list alternatives or exclusions, but there is no dedicated contact-creation sibling, so the context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_create_expenseA

Create an expense in FreeAgent — for purchases on a personal card or cash that need claiming back. Provide vendor, date, amount, description and category. If categoryUrl is omitted, auto-selects from vendor mapping. Optionally pass bankAccountId to auto-match and explain a corresponding bank transaction (e.g. if the same purchase also appears on a company card).

RECEIPTS: Before asking the user for a file, search connected email tools (Gmail, Outlook/M365) for a matching invoice. Use vendor name, amount and date as search terms. Download the PDF and pass it as fileBase64 + fileName. Also check local sources (Downloads folder, etc.) if the user has mentioned them.

ParametersJSON Schema
NameRequiredDescriptionDefault
vendorYesVendor / merchant name (e.g. 'IONOS Cloud')
datedOnYesExpense date YYYY-MM-DD
projectNoFreeAgent project URL (e.g. '/v2/projects/123') to tag the expense against, so it can be rebilled or reported per client. Use freeagent_list_projects to find it.
currencyNoISO 4217 currency code (default GBP)GBP
fileNameNoFile name for the receipt (e.g. 'receipt.pdf')
vatAmountNoVAT amount as string (e.g. '3.80')
fileBase64NoBase64-encoded receipt file (PDF, PNG, JPEG, etc.)
categoryUrlNoFreeAgent category URL (e.g. '/v2/categories/285'). Auto-selected from vendor if omitted.
contentTypeNoMIME type (e.g. 'application/pdf'). Inferred from fileName if omitted.
descriptionYesExpense description (e.g. 'Monthly cloud hosting')
grossAmountYesGross amount as string (e.g. '22.80')
bankAccountIdNoIf supplied, search this bank account for a matching unexplained transaction (same amount, date ±4 days) and link the expense to it.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since annotations only mark readOnly/idempotent/destructive hints, the description carries the burden here. It discloses auto-selection of category from vendor, optional bank-transaction matching via bankAccountId, and the required receipt-search workflow. It stops short of explaining the full side-effect of linking/explaining the bank transaction, which prevents a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two structured paragraphs with no filler. The core purpose is frontloaded, the optional bank-account matching is clearly explained, and the RECEIPTS section is practical workflow guidance rather than redundant paraphrasing of the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 12 parameters and no output schema, the description covers the main invocation intent, optional behaviors, and the required receipt-presearch step. It lacks an explicit note on what the tool returns after success, but that is not critical for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema covers 100% of parameters, giving a baseline of 3. The description enriches beyond the schema by tying parameters to real scenarios: personal card purchases, company-card overlap, and the vendor-and-date matching for bankAccountId. These additions help the agent select which parameters matter in context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States precisely 'Create an expense in FreeAgent' and narrows the use case to 'purchases on a personal card or cash that need claiming back'. This clearly distinguishes it from the mileage-expense sibling and tells the agent exactly what resource is being created.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete scenario for when this tool applies and even instructs the agent about receipt-related workflow before invocation. It does not explicitly mention alternatives such as freeagent_create_mileage_expense, so the agent is left to infer which sibling handles mileage claims.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_create_invoiceA

Raise an invoice in FreeAgent. Created as a DRAFT — it is not sent to the client. Use freeagent_update_invoice_status with 'mark_as_sent' once you have issued it.

Find the contact with freeagent_list_contacts and the income category with freeagent_list_categories (income categories, e.g. 001 Sales).

ParametersJSON Schema
NameRequiredDescriptionDefault
itemsYesInvoice line items — at least one
contactYesContact to invoice
datedOnYesInvoice date YYYY-MM-DD
projectNoProject this invoice belongs to
commentsNoNotes shown on the invoice
currencyNoISO 4217 currency (default: company currency)
referenceNoInvoice reference/number. FreeAgent auto-numbers if omitted.
poReferenceNoClient purchase order reference
discountPercentNoDiscount percentage (e.g. '10.0')
paymentTermsInDaysNoPayment terms in days (default 30) — sets the due date

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only provide readOnlyHint=false, idempotentHint=false, destructiveHint=false, which give minimal context. The description adds critical behavioral information: the invoice is created as a DRAFT and is not sent to the client. This is a key side effect not inferable from annotations or schema. It could go further by noting response shape, but the draft disclosure is substantial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short paragraphs: the first states the tool's purpose and key behavioral note, the second gives the lookup workflow. Every sentence contributes useful information; no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 10 parameters and no output schema, the description covers the essential workflow (draft creation, next step to send, prerequisite lookups). The schema handles parameter details. A more complete description might mention the response format or error handling, but for a create operation with a rich schema, this is adequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides 100% coverage for all 10 parameters, so the baseline is 3. The description adds practical guidance for two key parameters (contact and categoryUrl) by telling users to look them up with dedicated list tools and giving an example category URL ('001 Sales'). This goes beyond the schema's formal descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Raise an invoice in FreeAgent' — a specific verb with a clear resource. It immediately distinguishes itself from sibling tools like freeagent_update_invoice_status and freeagent_delete_invoice by clarifying it creates a draft, not a sent invoice.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this tool (raise a draft invoice) and directs users to freeagent_update_invoice_status for marking as sent. Also provides lookup guidance for contacts and income categories via freeagent_list_contacts and freeagent_list_categories, naming the exact sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_create_mileage_expenseA

Create a mileage expense in FreeAgent. Provide either origin + destination (requires ORS_API_KEY or GOOGLE_MAPS_API_KEY for distance lookup) or manualMiles for the journey distance. Set roundTrip=true to double the distance.

The claim value is calculated by FreeAgent from the mileage rate configured on the account (this is what HMRC reporting in FreeAgent uses). ratePence / cumulativeMilesYTD only produce an advisory estimate in the response for cross-checking — they do not change what is filed.

ParametersJSON Schema
NameRequiredDescriptionDefault
originNoOrigin address. Requires distance API key. Omit if providing manualMiles.
datedOnYesJourney date YYYY-MM-DD
projectNoFreeAgent project URL to tag the journey against
currencyNoISO 4217 currency code (default GBP)GBP
ratePenceNoPence per mile (e.g. 45) used only for the advisory estimate in the response. FreeAgent applies the mileage rate configured on the account when filing the claim.
roundTripNoDouble the distance for a return journey
descriptionYesJourney description (e.g. 'Office to client site, quarterly review')
destinationNoDestination address. Requires distance API key. Omit if providing manualMiles.
manualMilesNoJourney distance in miles (use instead of origin/destination)
vehicleTypeNoVehicle used for the journey (required by FreeAgent's mileage category)Car
cumulativeMilesYTDNoCumulative business miles already claimed this tax year. Used for HMRC threshold logic (high rate → low rate at threshold). Only relevant when ratePence is not set.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations providing no supportive hints (all false), the description carries the burden and excels. It discloses that the claim value is computed by FreeAgent, that ratePence/cumulativeMilesYTD are advisory only, and that distance lookup requires API keys. This goes well beyond the structured data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, front-loaded with the core action, and every sentence contributes critical information. It avoids fluff and redundancy while conveying complex behavioral nuances in two paragraphs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 11 parameters and no output schema, the description covers all essential usage aspects: input modes, distance computation, rounding behavior, and the distinction between advisory and filed values. No critical gap is apparent for an AI agent to select and invoke this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 100% schema coverage, the description adds significant semantic value by explaining the exclusive-or relationship between origin/destination and manualMiles, the effect of roundTrip, and the advisory nature of ratePence/cumulativeMilesYTD. This synthesis is not obvious from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb-resource pair ('Create a mileage expense in FreeAgent') that clearly identifies the tool's function. It implicitly distinguishes itself from the sibling 'create_expense' by focusing specifically on mileage, and the name reinforces this. No ambiguity exists.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly instructs when to use origin+destination versus manualMiles, and explains the roundTrip flag. It does not explicitly mention when to prefer this over freeagent_create_expense, but the context is clear enough for mileage-specific scenarios. A slight exclusion note would elevate it to 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_create_taskA

Create a task on a FreeAgent project. Tasks carry the billing rate that logged time is charged at.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesTask name (e.g. 'Delivery workshops')
statusNoTask status (default Active)Active
projectYesProject the task belongs to
currencyNoISO 4217 currency code
isBillableNoWhether time on this task is billable
billingRateNoRate charged per billing period (e.g. '850.00')
billingPeriodNoWhether the billing rate is per hour or per day

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a non-read-only, non-idempotent mutation. The description aligns with readOnlyHint=false and adds useful domain behavior (tasks set billing rates for logged time). It does not disclose idempotency implications, error behavior, or prerequisites, but annotations lower the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no fluff. The first sentence is front-loaded and directly states the operation; the second provides essential context about billing rate. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The core function and domain relevance are covered. Given the 100% schema coverage and absence of an output schema, the description doesn't need to explain return values. It could mention that the project must exist or contrast with timeslip creation, but these are minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with clear individual parameter descriptions. The description adds meaning by explaining that billingRate and billingPeriod define how logged time is charged, linking the billing parameters to the timeslip use case. This goes beyond the schema's isolated field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action and resource: 'Create a task on a FreeAgent project.' It distinguishes from sibling create tools (e.g., create_contact, create_expense) by specifically naming 'task' and adds domain context about billing rates, which ties it to timeslips.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by explaining that tasks carry the billing rate for logged time, suggesting a prerequisite before creating timeslips. However, it does not explicitly state when to use this tool versus alternatives like create_timeslip or list_tasks, nor does it mention exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_create_timeslipA

Log time against a FreeAgent project task. Defaults to the authenticated user as the person who did the work. Find the task with freeagent_list_tasks.

ParametersJSON Schema
NameRequiredDescriptionDefault
taskYesTask the time is logged against
userNoWho did the work (defaults to the authenticated user)
hoursYesHours worked as a decimal string (e.g. '7.5' for 7h30m)
commentNoWhat the time was spent on
datedOnYesDate the work was done YYYY-MM-DD
projectYesProject the work was for

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a non-read-only, non-destructive write operation. The description adds valuable behavioral context by noting that the user defaults to the authenticated user, which is not obvious from annotations alone. It also references a necessary lookup step, which helps set expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, immediately states the core purpose, and contains no filler or redundant information. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a create tool with 6 parameters and no output schema, the description covers the essential context: what it does, the default user behavior, and how to find the required task. It could mention the return value or potential errors, but the schema and annotations cover parameter details, so this is reasonably complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with each of the 6 parameters having a description, so the baseline is 3. The description adds little beyond the schema (e.g., 'defaults to the authenticated user' duplicates the user parameter description). No additional parameter meaning is provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Log time') and the resource ('against a FreeAgent project task'), which distinguishes it from sibling tools like freeagent_list_timeslips or freeagent_delete_timeslip. It also mentions the default user behavior, adding specificity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool (recording time against a task) and even points to the prerequisite tool 'freeagent_list_tasks' for finding the task. It does not explicitly name alternatives or exclusions, but for a create operation the usage context is sufficiently clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_delete_billA
DestructiveIdempotent

Permanently delete a FreeAgent bill.

ParametersJSON Schema
NameRequiredDescriptionDefault
billIdYesFreeAgent bill ID

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint true and idempotentHint true, so the safety profile is known. The word 'Permanently' reinforces irreversibility but adds no new behavioral context beyond annotations, and no details on side effects or error conditions are provided.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no filler. It front-loads the action verb and resource, making it immediately clear what the tool does.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple one-parameter schema and annotations covering safety, the description is adequate but lacks information about return values or behavior for non-existent bills. Without an output schema, this leaves some ambiguity for the agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully documents the only parameter, billId, including a pattern and description. The tool description adds no parameter-specific semantics, but with 100% schema coverage, the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Permanently delete a FreeAgent bill' with a specific verb and resource, making the tool's function unambiguous. It also distinguishes from sibling delete tools for invoices and timeslips by naming the resource type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives such as delete_invoice or delete_timeslip, nor any prerequisites or contextual conditions. The usage is only implied by the tool's name and action.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_delete_invoiceA
DestructiveIdempotent

Permanently delete a FreeAgent invoice. Only draft invoices can normally be deleted — cancel an issued invoice instead with freeagent_update_invoice_status.

ParametersJSON Schema
NameRequiredDescriptionDefault
invoiceIdYesFreeAgent invoice ID

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate destructive and idempotent behavior; the description adds the restriction that only draft invoices can normally be deleted and that deletion is permanent, which is valuable context beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both information-dense: the first states the core purpose, the second covers constraints and alternatives. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With one simple parameter, no output schema, and annotations covering destructive/idempotent hints, the description sufficiently covers the operation, including the critical draft-only limitation and the alternative for non-draft invoices.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already fully describes the single parameter (invoiceId with description and pattern). The description does not add additional parameter-specific details beyond that, so baseline applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Permanently delete') and the resource ('FreeAgent invoice'), and it distinguishes itself from sibling freeagent_update_invoice_status by mentioning the alternative for issued invoices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when deletion is allowed (draft invoices only) and directs users to freeagent_update_invoice_status for canceling issued invoices, providing clear when/alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_delete_timeslipB
DestructiveIdempotent

Delete a logged timeslip from FreeAgent.

ParametersJSON Schema
NameRequiredDescriptionDefault
timeslipIdYesFreeAgent timeslip ID

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description merely repeats the destructive nature already indicated by annotations (destructiveHint=true, readOnlyHint=false). It adds no extra context such as irreversibility, permission requirements, or behavior for non-existent timeslips. With annotations present, the description provides minimal added value beyond them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single clear sentence with no unnecessary words. It is concise and front-loaded, stating exactly what the tool does. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple delete tool with one parameter and annotations covering the safety profile, the description is minimally complete. However, it lacks any context about side effects or when deletion is allowed, which is a gap for a destructive operation. The presence of annotations partially compensates, but the description alone would not fully prepare an agent for nuanced situations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter timeslipId is fully documented in the schema with type, pattern, and description. The tool description does not mention the parameter at all, so it adds no additional meaning. Given 100% schema coverage, the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action 'Delete' and the resource 'a logged timeslip from FreeAgent', which is specific and distinguishes it from other delete tools targeting different resources (e.g., delete_bill, delete_invoice). It is not a tautology and adds the context 'logged' to clarify the subject.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives, nor any mention of prerequisites or consequences. The usage is only implied by the tool's purpose; it says nothing about conditions under which deletion is appropriate or what to do if the timeslip is referenced elsewhere.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_explain_transactionA
Idempotent

Approve or update a FreeAgent bank transaction explanation. Use this to:

  • Approve a 'marked for review' transaction (set markExplained=true)

  • Change the category or description of an explanation

  • Attach a receipt/invoice — PREFER filePath (a local file) or fileUrl (a download link); the server reads/encodes it. Re-attaching replaces any existing attachment. Get the explanationId from freeagent_list_transactions (explanation_id field).

RECEIPTS: Before asking the user for a file, search connected email tools (Gmail, Outlook/M365) for a matching invoice using vendor name, amount and date. Pass a download link as fileUrl, or save the PDF locally and pass filePath. Avoid fileBase64 for anything but tiny files — large inline base64 is unreliable. Also check local file sources (Downloads folder, etc.) if the user has mentioned them.

SAFETY: Only set markExplained=true when you have a confirmed receipt attached or the user has explicitly approved it.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileUrlNoURL of a receipt to download and attach (e.g. a Stripe 'Download invoice' link). The server fetches and encodes it — no need to handle bytes.
categoryNoFreeAgent category path (e.g. '/v2/categories/285'). Use freeagent_list_categories to find the right one.
fileNameNoFile name for the attachment (e.g. 'ionos-invoice-apr-2026.pdf')
filePathNoAbsolute path to a local file to attach (e.g. '/Users/you/Downloads/invoice.pdf'). The SERVER reads and base64-encodes it — PREFER THIS over fileBase64, which is unreliable for non-trivial files. fileName defaults to the file's name.
fileBase64NoBase64-encoded file to attach (receipt, invoice, screenshot — PDF, PNG, JPEG, etc.)
contentTypeNoMIME type of the file (e.g. 'application/pdf', 'image/jpeg', 'image/png'). Inferred from fileName/filePath if omitted.
descriptionNoHuman-readable description for the transaction (e.g. 'IONOS — Monthly cloud hosting')
explanationIdYesNumeric FreeAgent bank transaction explanation ID (from explanation_id in list_transactions)
markExplainedNoSet true to approve/reconcile the transaction. Only do this when evidence is attached or confirmed.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses key behavioral traits beyond the annotations: re-attaching replaces an existing attachment, the server reads/encodes filePath or fileUrl, large fileBase64 payloads are unreliable, and markExplained should be set only with confirmation. These details match the idempotentHint and readOnlyHint=false annotations, with no contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description uses clear sections (main actions, RECEIPTS, SAFETY) and bullet, front-loading the primary purpose before digging into attachment workflow. Every sentence serves a distinct purpose—no filler—and the structure lets the agent rapidly locate the relevant guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter mutation tool with no output schema, the description covers everything an agent needs: how to resolve the required explanationId, how to handle file options, how to source receipts, and when it is safe to approve. It also directs to relevant sibling tools where appropriate. The lack of explicit return-value documentation is acceptable because no output schema exists and the primary responsibility is to perform the mutation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter already has meaning. The description enriches that meaning with prioritizing filePath/fileUrl over fileBase64, explaining how fileName defaults when using filePath, and clarifying the safety condition on markExplained. This is above baseline but some repetition of schema text exists.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb-resource pair: 'Approve or update a FreeAgent bank transaction explanation' and immediately lists the three core actions it supports. It clearly distinguishes this tool from siblings like freeagent_list_transactions by directing the agent to obtain explanationId from that list tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use workflows: approving marked-for-review transactions, changing categories/descriptions, and attaching receipts. It also gives conditional guidance ('Only set markExplained=true when you have a confirmed receipt attached or the user has approved it') and cross-tool references, such as using freeagent_list_categories for the category path.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_get_invoiceA
Read-only

Fetch a single FreeAgent invoice in full, including its line items.

ParametersJSON Schema
NameRequiredDescriptionDefault
invoiceIdYesFreeAgent invoice ID

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the description builds on that by specifying what 'full' means (including line items). It adds useful behavioral context beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, succinct sentence that front-loads the verb and resource, with zero wasted words. It is immediately scannable and clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, single-parameter read-only tool with strong annotations, the description covers the essential purpose and return scope. No output schema exists, so the mention of line items helps set expectations. The tool's simplicity means nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter invoiceId is fully described in the schema (100% coverage), including its pattern. The description does not need to add parameter-level detail, and it doesn't, but it reinforces that the tool fetches by ID. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action ('Fetch') targeting a single resource ('a single FreeAgent invoice') and adds a key differentiator ('in full, including its line items'). This distinguishes it from sibling tools like freeagent_list_invoices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a specific invoice ID is known and full detail (including line items) is needed. It does not explicitly name alternatives or exclusions, but the clear scope ('single') and sibling context provide adequate guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_bank_accountsA
Read-only

List all bank accounts on the FreeAgent account. Returns account name, currency, current balance and status. Use this to find the bank account ID before listing transactions.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint=true and destructiveHint=false. The description adds that it returns specific fields but does not mention behavior like pagination or limits. It is consistent but not highly informative beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with purpose and output, with no wasted words. Every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with no parameters and good annotations, the description covers purpose, return fields, and a usage hint. It is complete enough for effective tool selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameters, so description coverage is 100%. The description implies the tool returns all accounts without filters, which is sufficient. Baseline of 4 for zero parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states it lists all bank accounts and details the returned fields (name, currency, balance, status). It clearly distinguishes from sibling tools which deal with expenses, categories, or transactions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description advises using this tool to find the bank account ID before listing transactions, providing explicit usage guidance. No when-not-to-use statements, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_billsA
Read-only

List FreeAgent bills — money the company owes to suppliers (accounts payable). Use view='open_or_overdue' to see what is still to pay.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoWhich bills to return (default: all)all
limitNoMaximum bills to return (default 50, max 100)
toDateNoLatest bill date YYYY-MM-DD
contactNoOnly bills from this supplier
projectNoOnly bills allocated to this project
fromDateNoEarliest bill date YYYY-MM-DD

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true and destructiveHint=false, so the description doesn't need to restate safety. It adds behavioral context by explaining that open_or_overdue views show unpaid bills, which is a useful nuance beyond the schema's enum.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the purpose, and the usage tip is compact and actionable. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with full schema coverage, no output schema, and annotations declaring safety, the description covers the essential usage. It could mention pagination or return format, but these are less critical for a simple list endpoint.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes all 6 parameters with 100% coverage, so the baseline is 3. The description adds slight extra meaning for the 'view' parameter, but overall the schema carries the parameter documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'List' with the resource 'FreeAgent bills' and clarifies the domain meaning as 'money the company owes to suppliers (accounts payable)', which distinguishes it from sibling tools like list_invoices, create_bill, and delete_bill.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides a clear usage directive: 'Use view='open_or_overdue' to see what is still to pay.' This gives a concrete use case, but it doesn't explicitly contrast with alternatives or state when not to use the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_categoriesA
Read-only

List FreeAgent expense categories (chart of accounts). Returns category URL, description, nominal code and group. Use the category URL when creating expenses or explaining transactions. Cached after first call.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds that results are cached after the first call, which is additional behavioral context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences that front-load the action and purpose. Could be slightly trimmed but effectively communicates key information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite no output schema, the description lists return fields and mentions caching, providing adequate context for a simple list tool with no parameters. Sufficient for an agent to understand and invoke correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist (schema coverage 100%), so parameter semantics are inherently satisfied. Baseline 4 per guidelines for zero-parameter tools.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it lists FreeAgent expense categories (chart of accounts) and specifies returned fields (URL, description, nominal code, group). This distinguishes it from sibling tools that deal with expenses or transactions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to use the category URL when creating expenses or explaining transactions, providing clear use context. No explicit when-not-to-use, but the guideline is sufficient for this simple tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_contactsA
Read-only

List FreeAgent contacts (clients and suppliers). Returns contact URL, name, email, status and outstanding account balance. Use the contact URL when raising an invoice or entering a supplier bill.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoWhich contacts to return (default: active)active
limitNoMaximum contacts to fetch (default 100, max 1000). The server pages through as many requests as needed; `search` is applied to everything fetched.
searchNoCase-insensitive filter on name or email, applied to the results

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safe read-only nature is established. The description adds the return field list and the note about using the contact URL in invoices/bills, which is useful but not additional behavioral disclosure beyond what annotations and schema provide. No contradictions exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The core action is front-loaded ('List FreeAgent contacts'), and the second sentence adds actionable guidance about the contact URL. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Considering the low complexity, full schema coverage, and strong annotations, the description is nearly complete. It lists return fields, which compensates for the lack of an output schema, and the parameter descriptions cover pagination and filtering. It does not need to explain simple details like status meaning, so it is complete for the tool's purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each parameter (view, limit, search) fully described. The description's mention of 'clients and suppliers' aligns with the view enum but does not add meaningful semantic detail beyond the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description begins with 'List FreeAgent contacts (clients and suppliers)', using a specific verb (List) and resource (FreeAgent contacts) with added scope (clients and suppliers) and return fields. It is unambiguous and distinguishes itself from sibling tools such as create_contact or list_invoices by being the only contact-listing tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool versus alternatives, but it provides downstream usage context: 'Use the contact URL when raising an invoice or entering a supplier bill.' This implies a need for contact data when performing those operations, but there are no explicit exclusions or alternative tool mentions, so usage guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_invoicesA
Read-only

List FreeAgent invoices with their status and outstanding balance. Use view='overdue' to chase late payers, 'open_or_overdue' for everything unpaid, or 'draft' for invoices not yet issued.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoWhich invoices to return (default: all)all
limitNoMaximum invoices to return (default 50, max 100)
toDateNoLatest invoice date YYYY-MM-DD
contactNoOnly invoices for this contact
projectNoOnly invoices for this project
fromDateNoEarliest invoice date YYYY-MM-DD

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is established. The description adds useful context about the returned data (status, outstanding balance) and filter behavior via views, but does not disclose pagination limits or API-specific edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the primary action and resource. The view guidance is concise and actionable, and every sentence earns its place without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description does mention key return fields (status, outstanding balance), which partially offsets that gap. With all parameters optional and well-documented in the schema, and annotations indicating a safe list operation, the description is largely complete. Minor omission: no mention of default ordering or result limit behavior beyond the schema's 'default 50, max 100'.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 100% parameter description coverage, including enums, regex patterns, and defaults. The description only re-emphasizes some view values and adds no new syntax or formatting details beyond the schema, so a baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the verb 'List' and resource 'FreeAgent invoices', and specifies the output includes status and outstanding balance. It distinguishes itself from sibling tools like list_bills and list_contacts, and the mention of specific views (overdue, open_or_overdue, draft) reinforces scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance on when to use different view values (e.g., 'overdue' to chase late payers, 'draft' for unissued invoices), which is valuable context. However, it does not mention when not to use this tool or point to alternatives like get_invoice for individual invoice details, so it stops short of full when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_projectsA
Read-only

List FreeAgent projects. Returns project URL, name, status and contact. Use the project URL to tag an expense to a client engagement via freeagent_create_expense.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoWhich projects to return (default: active)active

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description discloses what the tool returns (project URL, name, status, contact) and that the project URL is used for expense tagging. This adds behavioral context without contradicting annotations, though it omits details like pagination or authentication.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, immediately states the action and results. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with one optional parameter, the description covers purpose, return values, and a downstream use case. The output schema is absent, but the listed return fields suffice.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema fully documents the single 'view' parameter with an enum and default, so the schema carries the parameter meaning. The description itself adds no additional parameter information, but since schema coverage is 100%, a baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'List FreeAgent projects', a specific verb+resource that clearly identifies the tool's function. It also lists returned fields (URL, name, status, contact), distinguishing it from other list tools like freeagent_list_tasks or freeagent_list_contacts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool: when you need project details, particularly to tag expenses to client engagements via freeagent_create_expense. It doesn't explicitly exclude alternative tools or state when-not-to-use, but the integration hint is valuable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_tasksA
Read-only

List project tasks in FreeAgent. Time is always logged against a task, so use this to find the task URL before creating a timeslip.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoWhich tasks to return (default: active)active
limitNoMaximum tasks to return (default 50, max 100)
projectNoOnly tasks belonging to this project

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds the domain fact that time is always logged against a task, but does not disclose tool-specific behaviors such as default view, pagination handling, or response structure. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the purpose and immediately followed by actionable usage guidance. There is zero redundancy or irrelevant detail, earning a perfect score for conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with fully described parameters and read-only annotations, the description covers the core purpose and a key use case. It does not mention return format or fields, but this is partially mitigated by the absence of an output schema and the simplicity of the tool. Overall, it is sufficiently complete for an agent to select and use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: all three parameters (view, limit, project) have descriptive text and constraints already. The tool description adds no additional parameter semantics beyond what the schema provides, so a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function with a specific verb and resource: 'List project tasks in FreeAgent.' It also distinguishes itself from sibling tools like freeagent_list_projects and freeagent_list_timeslips by noting that tasks are tied to time logging, which makes its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage context: 'Time is always logged against a task, so use this to find the task URL before creating a timeslip.' This tells the agent exactly when to use this tool and connects it to the downstream action of creating a timeslip, effectively naming the alternative or next step.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_timeslipsA
Read-only

List logged time in FreeAgent for a date range. Use view='unbilled' to find time that has not yet been invoiced. Returns per-project totals alongside the individual entries.

ParametersJSON Schema
NameRequiredDescriptionDefault
taskNoOnly time on this task
userNoOnly time logged by this user
viewNoWhich timeslips to return (default: all)all
limitNoMaximum timeslips to return (default 100, max 100)
toDateYesEnd of the date range YYYY-MM-DD
projectNoOnly time on this project
fromDateYesStart of the date range YYYY-MM-DD

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context beyond annotations by noting that the tool returns per-project totals alongside individual entries and that the 'unbilled' view filters to uninvoiced timeslips, giving the agent a clearer picture of the output and filtering behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded, stating the core purpose in the first sentence and adding relevant usage details in the following two sentences. Every sentence earns its place without redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only listing tool with a rich schema and annotations, the description provides sufficient context: it identifies the operation, the date-range scope, a specific view mode, and the shape of the return data. It could mention pagination or limits, but the schema already documents the limit parameter, so this is not a significant gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema thoroughly describes all parameters (100% coverage), so the baseline is 3. The description adds marginal semantic value by explaining the meaning of 'view='unbilled'' in context, but does not significantly enhance understanding of the other parameters beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists logged time in FreeAgent for a date range, using a specific verb and resource. It also differentiates from siblings like freeagent_create_timeslip and freeagent_delete_timeslip by focusing on the listing operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for using the tool (listing time in a date range) and gives a specific use case ('view='unbilled'') to find uninvoiced time. It does not explicitly name alternatives or exclude other tools, but the usage context is clear enough for an agent to select it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_list_transactionsA
Read-only

List bank account transactions from FreeAgent. By default returns unexplained (unreconciled) transactions. Use bankAccountId from freeagent_list_bank_accounts. Returns id, date, description, amount, and explanation details (category, marked_for_review) for each entry. After listing, if the task involves reconciliation, search available email or file sources for matching receipts — do not ask the user to provide files before checking email (Gmail, Outlook, etc.) and local sources first.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number for pagination (default 1)
viewNoWhich transactions to return. Defaults to unexplained. Use 'marked_for_review' for auto-categorised transactions awaiting approval.unexplained
limitNoMax entries to return (default 50, max 100)
toDateNoEnd date filter YYYY-MM-DD (inclusive)
fromDateNoStart date filter YYYY-MM-DD (inclusive)
bankAccountIdYesNumeric FreeAgent bank account ID (e.g. '1877156')

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds default filtering behavior and output fields, but it does not describe pagination, rate limits, or edge cases. This is moderate additional value, thus a 3.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first three sentences are clear and front-loaded, but the final sentence about checking email/local sources before asking the user is a lengthy tangent that, while useful, is not essential to describing the tool's core function. This prevents a top score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple listing nature, the schema's full parameter documentation, and the annotations, the description provides enough context: default view, required ID source, and return fields. It lacks only deeper response details, but the mentioned fields suffice. A 4 is justified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers all 6 parameters with descriptions (100% coverage), so the baseline is 3. The description adds a useful pointer for bankAccountId, but no additional syntax or format details beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List bank account transactions from FreeAgent' with a specific verb and resource. It further clarifies the default view (unexplained) and return fields, making it distinct from sibling listing tools for contacts, invoices, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description instructs to 'Use bankAccountId from freeagent_list_bank_accounts', providing a clear prerequisite. It implies the tool's intended use for listing transactions but does not explicitly state alternatives or when-not-to-use cases, so a 4 is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_profit_and_lossA
Read-only

FreeAgent profit and loss summary — income, expenses, operating profit, corporation tax estimate, dividends and retained profit. Defaults to the current accounting year.

ParametersJSON Schema
NameRequiredDescriptionDefault
toDateNoPeriod end YYYY-MM-DD (default: today)
fromDateNoPeriod start YYYY-MM-DD (default: start of the current accounting year)

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint true and destructiveHint false. The description adds value by specifying the content of the summary (income, expenses, operating profit, corporation tax estimate, dividends, retained profit) and the default period. It does not mention limitations like pagination or exact output structure, but the added detail goes beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the tool's purpose and uses a dash to introduce key details. It is concise and every word adds value, with no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only reporting tool with two optional parameters and good annotations, the description is sufficiently complete. It lists the expected components of the summary, which compensates for the absence of an output schema. No critical information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides full descriptions for both parameters (fromDate and toDate), including their defaults and formats. The description's mention of 'current accounting year' merely echoes the schema defaults and adds no new semantic meaning. Schema coverage is 100%, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as a FreeAgent profit and loss summary, enumerating the included components (income, expenses, operating profit, etc.). This distinguishes it from sibling tools like trial balance or company summary. However, it lacks an explicit action verb (e.g., 'get' or 'list'), instead using a noun phrase that closely mirrors the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides context that the tool defaults to the current accounting year, giving some usage guidance. It implies this is the go-to tool for P&L data, but it does not explicitly state when to use it over alternatives or mention excluded scenarios. No clear when-not-to-use guidance is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_tax_timelineA
Read-only

Upcoming tax and filing deadlines from FreeAgent — VAT returns, corporation tax, Companies House filings, self assessment — with amounts due and dates.

ParametersJSON Schema
NameRequiredDescriptionDefault
includePersonalNoInclude personal (self assessment) items as well as company ones

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context by specifying the types of tax items included and that amounts and dates are provided, which goes beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that efficiently conveys the tool's purpose and key returns without any filler. It earns its place with relevant details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only report with one optional parameter and no output schema, the description covers the essential return content (amounts due and dates) and the scope thoroughly. It is sufficiently complete for an agent to select and invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, as the only parameter includePersonal has a clear description in the schema. The tool description does not add additional meaning about the parameter, so it stays at the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as providing a timeline of upcoming tax and filing deadlines from FreeAgent, naming specific categories (VAT, corporation tax, Companies House, self assessment) and what it returns (amounts due and dates). This distinguishes it from sibling tools like freeagent_profit_and_loss or freeagent_company_summary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies usage for tax-related deadline inquiries, which provides a clear context. It does not explicitly exclude other tools or mention alternatives, but the specificity of the scope makes the intended use obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_trial_balanceA
Read-only

FreeAgent trial balance — the balance on every nominal account. Credits are negative, debits positive. Useful for a full financial position.

ParametersJSON Schema
NameRequiredDescriptionDefault
asAtNoBalance date YYYY-MM-DD (default: today)
nonZeroOnlyNoOmit accounts with a zero balance (default true)

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses a key behavioral detail (sign convention) and mentions 'every nominal account', but this conflicts with the nonZeroOnly parameter default (true), which omits zero-balance accounts. This creates ambiguity about actual default behavior. Annotations already cover read-only/destructive safety.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the tool name and core purpose. The additional sign convention is essential. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple report tool with no output schema, the description covers the main output (balances) and sign convention, but fails to mention the nonZeroOnly filter's default behavior, which conflicts with 'every account'. It also does not describe return format (though not required by schema). The ambiguity reduces completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are well-documented. However, the description's phrase 'every nominal account' contradicts the nonZeroOnly parameter's default, potentially misleading agents about filtering behavior. The description does not add positive value beyond the schema and introduces confusion.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reports the balance on every nominal account with a sign convention (credits negative, debits positive). It does not explicitly distinguish from sibling financial reports like freeagent_profit_and_loss, but the specific resource (trial balance) is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear context for use ('Useful for a full financial position') but lacks explicit guidance on when to prefer this over alternatives or when not to use it. No alternative tools are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeagent_update_invoice_statusA
DestructiveIdempotent

Change an invoice's status in FreeAgent: mark_as_sent (issue it), mark_as_draft (pull it back), mark_as_scheduled, or mark_as_cancelled. These change status only — no email is sent to the client.

ParametersJSON Schema
NameRequiredDescriptionDefault
invoiceIdYesFreeAgent invoice ID
transitionYesThe status change to apply

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal destructive and non-read-only behavior, but the description adds valuable context: 'no email is sent to the client' and explains what each transition does (e.g., 'issue it', 'pull it back'). This goes beyond the structured data and clarifies a key side-effect that users would otherwise assume. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences front-load the purpose and immediately list the supported transitions. Every word earns its place, and the behavioral note about email is a single clause. No fluff or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a simple mutation with no output schema, and the description covers the core behavior, transitions, and a key side-effect (no email). It could mention prerequisites like invoice state, but the description is sufficient for most use cases given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds meaning beyond the schema by explaining the transition enum values in plain language (mark_as_sent = issue it, mark_as_draft = pull it back), which helps the agent select the right transition. This elevates it above the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool changes an invoice's status, enumerates the exact transitions (mark_as_sent, mark_as_draft, mark_as_scheduled, mark_as_cancelled), and explains their effects. This distinguishes it from sibling invoice tools like list_invoices or get_invoice which don't modify status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool: whenever an invoice's status needs to be changed. It doesn't explicitly mention alternatives or exclusions, but the scope is unambiguous given the sibling context. A clear 'use this instead of X' would push it to 5, but it's still well-contextualized.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 4 tool updatesv3.0.1
    • Changedfreeagent_create_bill15 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / contact
        Added value: +{
        +  "description": "Supplier the bill is from — create one with freeagent_create_contact",
        +  "pattern": "^(?:https:\\/\\/api\\.freeagent\\.com)?\\/v2\\/contacts\\/\\d+$",
        +  "type": "string"
        +}
      • addedInput schema / properties / contentType
        Added value: +{
        +  "description": "MIME type. Inferred from fileName if omitted.",
        +  "type": "string"
        +}
      • addedInput schema / properties / currency
        Added value: +{
        +  "description": "ISO 4217 currency (default: company currency)",
        +  "pattern": "^[A-Z]{3}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / datedOn
        Added value: +{
        +  "description": "Bill date YYYY-MM-DD",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / dueOn
        Added value: +{
        +  "description": "Payment due date YYYY-MM-DD",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / fileBase64
        Added value: +{
        +  "description": "Base64-encoded supplier invoice (PDF, PNG, JPEG)",
        +  "maxLength": 6990000,
        +  "type": "string"
        +}
      • addedInput schema / properties / fileName
        Added value: +{
        +  "description": "File name (e.g. 'invoice.pdf')",
        +  "type": "string"
        +}
      • addedInput schema / properties / items
        Added value: +{
        +  "description": "Bill line items — at least one, at most 40",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "categoryUrl": {
        +        "description": "Spending category for this line",
        +        "pattern": "^(?:https:\\/\\/api\\.freeagent\\.com)?\\/v2\\/categories\\/\\d+$",
        +        "type": "string"
        +      },
        +      "description": {
        +        "description": "Line description",
        +        "maxLength": 500,
        +        "type": "string"
        +      },
        +      "salesTaxRate": {
        +        "description": "VAT rate (e.g. '20.0')",
        +        "pattern": "^\\d+(\\.\\d+)?$",
        +        "type": "string"
        +      },
        +      "totalValue": {
        +        "description": "Line value INCLUDING tax (e.g. '120.00'). Must be positive — a supplier credit is a credit note, not a negative bill line.",
        +        "pattern": "^\\d+(\\.\\d{1,2})?$",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "categoryUrl",
        +      "totalValue"
        +    ],
        +    "type": "object"
        +  },
        +  "maxItems": 40,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • addedInput schema / properties / project
        Added value: +{
        +  "description": "Project to allocate this bill to",
        +  "pattern": "^(?:https:\\/\\/api\\.freeagent\\.com)?\\/v2\\/projects\\/\\d+$",
        +  "type": "string"
        +}
      • addedInput schema / properties / rebillFactor
        Added value: +{
        +  "description": "Markup percentage or fixed price — required for markup/price",
        +  "pattern": "^\\d+(\\.\\d+)?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / rebillType
        Added value: +{
        +  "description": "How to rebill this to the client",
        +  "enum": [
        +    "cost",
        +    "markup",
        +    "price"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / reference
        Added value: +{
        +  "description": "Supplier's invoice reference (e.g. 'INV-2049')",
        +  "maxLength": 100,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • addedInput schema / required
        Added value: +[
        +  "contact",
        +  "reference",
        +  "datedOn",
        +  "dueOn",
        +  "items"
        +]
    • Changedfreeagent_create_contact15 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / address1
        Added value: +{
        +  "description": "First line of the address",
        +  "maxLength": 200,
        +  "type": "string"
        +}
      • addedInput schema / properties / address2
        Added value: +{
        +  "description": "Second line of the address",
        +  "maxLength": 200,
        +  "type": "string"
        +}
      • addedInput schema / properties / chargeSalesTax
        Added value: +{
        +  "description": "Whether to charge sales tax to this contact (default: Auto)",
        +  "enum": [
        +    "Auto",
        +    "Always",
        +    "Never"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / contactNameOnInvoices
        Added value: +{
        +  "description": "Show the person's name rather than the organisation on invoices",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / country
        Added value: +{
        +  "description": "Country (e.g. 'United Kingdom')",
        +  "maxLength": 100,
        +  "type": "string"
        +}
      • addedInput schema / properties / email
        Added value: +{
        +  "description": "Contact email address",
        +  "format": "email",
        +  "type": "string"
        +}
      • addedInput schema / properties / firstName
        Added value: +{
        +  "description": "Contact first name",
        +  "maxLength": 100,
        +  "type": "string"
        +}
      • addedInput schema / properties / lastName
        Added value: +{
        +  "description": "Contact last name",
        +  "maxLength": 100,
        +  "type": "string"
        +}
      • addedInput schema / properties / organisationName
        Added value: +{
        +  "description": "Company name (e.g. 'Example Client Ltd')",
        +  "maxLength": 200,
        +  "type": "string"
        +}
      • addedInput schema / properties / phoneNumber
        Added value: +{
        +  "description": "Contact phone number",
        +  "maxLength": 50,
        +  "type": "string"
        +}
      • addedInput schema / properties / postcode
        Added value: +{
        +  "description": "Postcode or ZIP",
        +  "maxLength": 20,
        +  "type": "string"
        +}
      • addedInput schema / properties / region
        Added value: +{
        +  "description": "County, region or state",
        +  "maxLength": 100,
        +  "type": "string"
        +}
      • addedInput schema / properties / town
        Added value: +{
        +  "description": "Town or city",
        +  "maxLength": 100,
        +  "type": "string"
        +}
    • Changedfreeagent_create_expense15 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / bankAccountId
        Added value: +{
        +  "description": "If supplied, search this bank account for a matching unexplained transaction (same amount, date ±4 days) and link the expense to it.",
        +  "type": "string"
        +}
      • addedInput schema / properties / categoryUrl
        Added value: +{
        +  "description": "FreeAgent category URL (e.g. '/v2/categories/285'). Auto-selected from vendor if omitted.",
        +  "pattern": "^(?:https:\\/\\/api\\.freeagent\\.com)?\\/v2\\/categories\\/\\d+$",
        +  "type": "string"
        +}
      • addedInput schema / properties / contentType
        Added value: +{
        +  "description": "MIME type (e.g. 'application/pdf'). Inferred from fileName if omitted.",
        +  "type": "string"
        +}
      • addedInput schema / properties / currency
        Added value: +{
        +  "default": "GBP",
        +  "description": "ISO 4217 currency code (default GBP)",
        +  "pattern": "^[A-Z]{3}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / datedOn
        Added value: +{
        +  "description": "Expense date YYYY-MM-DD",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        +  "type": "string"
        +}
      • addedInput schema / properties / description
        Added value: +{
        +  "description": "Expense description (e.g. 'Monthly cloud hosting')",
        +  "maxLength": 1000,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • addedInput schema / properties / fileBase64
        Added value: +{
        +  "description": "Base64-encoded receipt file (PDF, PNG, JPEG, etc.)",
        +  "maxLength": 10000000,
        +  "type": "string"
        +}
      • addedInput schema / properties / fileName
        Added value: +{
        +  "description": "File name for the receipt (e.g. 'receipt.pdf')",
        +  "type": "string"
        +}
      • addedInput schema / properties / grossAmount
        Added value: +{
        +  "description": "Gross amount as string (e.g. '22.80')",
        +  "pattern": "^\\d+(\\.\\d{1,2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / project
        Added value: +{
        +  "description": "FreeAgent project URL (e.g. '/v2/projects/123') to tag the expense against, so it can be rebilled or reported per client. Use freeagent_list_projects to find it.",
        +  "pattern": "^(?:https:\\/\\/api\\.freeagent\\.com)?\\/v2\\/projects\\/\\d+$",
        +  "type": "string"
        +}
      • addedInput schema / properties / vatAmount
        Added value: +{
        +  "description": "VAT amount as string (e.g. '3.80')",
        +  "pattern": "^\\d+(\\.\\d{1,2})?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / vendor
        Added value: +{
        +  "description": "Vendor / merchant name (e.g. 'IONOS Cloud')",
        +  "maxLength": 200,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • addedInput schema / required
        Added value: +[
        +  "vendor",
        +  "datedOn",
        +  "grossAmount",
        +  "description"
        +]
    • Changedfreeagent_explain_transaction12 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / category
        Added value: +{
        +  "description": "FreeAgent category path (e.g. '/v2/categories/285'). Use freeagent_list_categories to find the right one.",
        +  "pattern": "^\\/v2\\/categories\\/\\d+$",
        +  "type": "string"
        +}
      • addedInput schema / properties / contentType
        Added value: +{
        +  "description": "MIME type of the file (e.g. 'application/pdf', 'image/jpeg', 'image/png'). Inferred from fileName/filePath if omitted.",
        +  "type": "string"
        +}
      • addedInput schema / properties / description
        Added value: +{
        +  "description": "Human-readable description for the transaction (e.g. 'IONOS — Monthly cloud hosting')",
        +  "type": "string"
        +}
      • addedInput schema / properties / explanationId
        Added value: +{
        +  "description": "Numeric FreeAgent bank transaction explanation ID (from explanation_id in list_transactions)",
        +  "minLength": 1,
        +  "type": "string"
        +}
      • addedInput schema / properties / fileBase64
        Added value: +{
        +  "description": "Base64-encoded file to attach (receipt, invoice, screenshot — PDF, PNG, JPEG, etc.)",
        +  "maxLength": 10000000,
        +  "type": "string"
        +}
      • addedInput schema / properties / fileName
        Added value: +{
        +  "description": "File name for the attachment (e.g. 'ionos-invoice-apr-2026.pdf')",
        +  "type": "string"
        +}
      • addedInput schema / properties / filePath
        Added value: +{
        +  "description": "Absolute path to a local file to attach (e.g. '/Users/you/Downloads/invoice.pdf'). The SERVER reads and base64-encodes it — PREFER THIS over fileBase64, which is unreliable for non-trivial files. fileName defaults to the file's name.",
        +  "type": "string"
        +}
      • addedInput schema / properties / fileUrl
        Added value: +{
        +  "description": "URL of a receipt to download and attach (e.g. a Stripe 'Download invoice' link). The server fetches and encodes it — no need to handle bytes.",
        +  "format": "uri",
        +  "type": "string"
        +}
      • addedInput schema / properties / markExplained
        Added value: +{
        +  "default": false,
        +  "description": "Set true to approve/reconcile the transaction. Only do this when evidence is attached or confirmed.",
        +  "type": "boolean"
        +}
      • addedInput schema / required
        Added value: +[
        +  "explanationId"
        +]
  2. 26 tool updatesv3.0.0
    • Addedfreeagent_aged_creditors
    • Addedfreeagent_aged_debtors
    • Addedfreeagent_company_summary
    • Addedfreeagent_create_bill
    • Addedfreeagent_create_contact
    • Changedfreeagent_create_expense14 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
      • removedInput schema / properties / bankAccountId
        Removed value: -{
        -  "description": "If supplied, search this bank account for a matching unexplained transaction (same amount, date ±4 days) and link the expense to it.",
        -  "type": "string"
        -}
      • removedInput schema / properties / categoryUrl
        Removed value: -{
        -  "description": "FreeAgent category URL (e.g. '/v2/categories/285'). Auto-selected from vendor if omitted.",
        -  "pattern": "^\\/v2\\/categories\\/\\d+$",
        -  "type": "string"
        -}
      • removedInput schema / properties / contentType
        Removed value: -{
        -  "description": "MIME type (e.g. 'application/pdf'). Inferred from fileName if omitted.",
        -  "type": "string"
        -}
      • removedInput schema / properties / currency
        Removed value: -{
        -  "default": "GBP",
        -  "description": "ISO 4217 currency code (default GBP)",
        -  "maxLength": 3,
        -  "minLength": 3,
        -  "type": "string"
        -}
      • removedInput schema / properties / datedOn
        Removed value: -{
        -  "description": "Expense date YYYY-MM-DD",
        -  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        -  "type": "string"
        -}
      • removedInput schema / properties / description
        Removed value: -{
        -  "description": "Expense description (e.g. 'Monthly cloud hosting')",
        -  "maxLength": 1000,
        -  "minLength": 1,
        -  "type": "string"
        -}
      • removedInput schema / properties / fileBase64
        Removed value: -{
        -  "description": "Base64-encoded receipt file (PDF, PNG, JPEG, etc.)",
        -  "maxLength": 10000000,
        -  "type": "string"
        -}
      • removedInput schema / properties / fileName
        Removed value: -{
        -  "description": "File name for the receipt (e.g. 'receipt.pdf')",
        -  "type": "string"
        -}
      • removedInput schema / properties / grossAmount
        Removed value: -{
        -  "description": "Gross amount as string (e.g. '22.80')",
        -  "minLength": 1,
        -  "type": "string"
        -}
      • removedInput schema / properties / vatAmount
        Removed value: -{
        -  "description": "VAT amount as string (e.g. '3.80')",
        -  "type": "string"
        -}
      • removedInput schema / properties / vendor
        Removed value: -{
        -  "description": "Vendor / merchant name (e.g. 'IONOS Cloud')",
        -  "maxLength": 200,
        -  "minLength": 1,
        -  "type": "string"
        -}
      • removedInput schema / required
        Removed value: -[
        -  "vendor",
        -  "datedOn",
        -  "grossAmount",
        -  "description"
        -]
    • Addedfreeagent_create_invoice
    • Changedfreeagent_create_mileage_expense7 fields changed
      • removedInput schema / properties / currency / maxLength
        Removed value: -3
      • removedInput schema / properties / currency / minLength
        Removed value: -3
      • addedInput schema / properties / currency / pattern
        Added value: +"^[A-Z]{3}$"
      • changedInput schema / properties / description / description
        Previous value: -"Journey description (e.g. 'Wakefield to Ackworth TT Club, coaching session')"New value: +"Journey description (e.g. 'Office to client site, quarterly review')"
      • addedInput schema / properties / project
        Added value: +{
        +  "description": "FreeAgent project URL to tag the journey against",
        +  "pattern": "^(?:https:\\/\\/api\\.freeagent\\.com)?\\/v2\\/projects\\/\\d+$",
        +  "type": "string"
        +}
      • changedInput schema / properties / ratePence / description
        Previous value: -"Pence per mile (e.g. 45). If omitted, uses MILEAGE_RATE_PENCE env var or HMRC rates (configurable via env vars, defaults to 45p/25p with threshold logic)."New value: +"Pence per mile (e.g. 45) used only for the advisory estimate in the response. FreeAgent applies the mileage rate configured on the account when filing the claim."
      • addedInput schema / properties / vehicleType
        Added value: +{
        +  "default": "Car",
        +  "description": "Vehicle used for the journey (required by FreeAgent's mileage category)",
        +  "enum": [
        +    "Car",
        +    "Motorcycle",
        +    "Bicycle"
        +  ],
        +  "type": "string"
        +}
    • Addedfreeagent_create_task
    • Addedfreeagent_create_timeslip
    • Addedfreeagent_delete_bill
    • Addedfreeagent_delete_invoice
    • Addedfreeagent_delete_timeslip
    • Changedfreeagent_explain_transaction12 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
      • removedInput schema / properties / category
        Removed value: -{
        -  "description": "FreeAgent category path (e.g. '/v2/categories/285'). Use freeagent_list_categories to find the right one.",
        -  "pattern": "^\\/v2\\/categories\\/\\d+$",
        -  "type": "string"
        -}
      • removedInput schema / properties / contentType
        Removed value: -{
        -  "description": "MIME type of the file (e.g. 'application/pdf', 'image/jpeg', 'image/png'). Inferred from fileName/filePath if omitted.",
        -  "type": "string"
        -}
      • removedInput schema / properties / description
        Removed value: -{
        -  "description": "Human-readable description for the transaction (e.g. 'IONOS — Monthly cloud hosting')",
        -  "type": "string"
        -}
      • removedInput schema / properties / explanationId
        Removed value: -{
        -  "description": "Numeric FreeAgent bank transaction explanation ID (from explanation_id in list_transactions)",
        -  "minLength": 1,
        -  "type": "string"
        -}
      • removedInput schema / properties / fileBase64
        Removed value: -{
        -  "description": "Base64-encoded file to attach (receipt, invoice, screenshot — PDF, PNG, JPEG, etc.)",
        -  "maxLength": 10000000,
        -  "type": "string"
        -}
      • removedInput schema / properties / fileName
        Removed value: -{
        -  "description": "File name for the attachment (e.g. 'ionos-invoice-apr-2026.pdf')",
        -  "type": "string"
        -}
      • removedInput schema / properties / filePath
        Removed value: -{
        -  "description": "Absolute path to a local file to attach (e.g. '/Users/you/Downloads/invoice.pdf'). The SERVER reads and base64-encodes it — PREFER THIS over fileBase64, which is unreliable for non-trivial files. fileName defaults to the file's name.",
        -  "type": "string"
        -}
      • removedInput schema / properties / fileUrl
        Removed value: -{
        -  "description": "URL of a receipt to download and attach (e.g. a Stripe 'Download invoice' link). The server fetches and encodes it — no need to handle bytes.",
        -  "format": "uri",
        -  "type": "string"
        -}
      • removedInput schema / properties / markExplained
        Removed value: -{
        -  "default": false,
        -  "description": "Set true to approve/reconcile the transaction. Only do this when evidence is attached or confirmed.",
        -  "type": "boolean"
        -}
      • removedInput schema / required
        Removed value: -[
        -  "explanationId"
        -]
    • Addedfreeagent_get_invoice
    • Addedfreeagent_list_bills
    • Addedfreeagent_list_contacts
    • Addedfreeagent_list_invoices
    • Addedfreeagent_list_projects
    • Addedfreeagent_list_tasks
    • Addedfreeagent_list_timeslips
    • Changedfreeagent_list_transactions2 fields changed
      • changedInput schema / properties / limit / description
        Previous value: -"Max entries to return (default 50, max 200)"New value: +"Max entries to return (default 50, max 100)"
      • changedInput schema / properties / limit / maximum
        Previous value: -200New value: +100
    • Addedfreeagent_profit_and_loss
    • Addedfreeagent_tax_timeline
    • Addedfreeagent_trial_balance
    • Addedfreeagent_update_invoice_status
  3. 1 tool updatev2.2.0
    • Changedfreeagent_explain_transaction3 fields changed
      • changedInput schema / properties / contentType / description
        Previous value: -"MIME type of the file (e.g. 'application/pdf', 'image/jpeg', 'image/png'). Inferred from fileName if omitted."New value: +"MIME type of the file (e.g. 'application/pdf', 'image/jpeg', 'image/png'). Inferred from fileName/filePath if omitted."
      • addedInput schema / properties / filePath
        Added value: +{
        +  "description": "Absolute path to a local file to attach (e.g. '/Users/you/Downloads/invoice.pdf'). The SERVER reads and base64-encodes it — PREFER THIS over fileBase64, which is unreliable for non-trivial files. fileName defaults to the file's name.",
        +  "type": "string"
        +}
      • addedInput schema / properties / fileUrl
        Added value: +{
        +  "description": "URL of a receipt to download and attach (e.g. a Stripe 'Download invoice' link). The server fetches and encodes it — no need to handle bytes.",
        +  "format": "uri",
        +  "type": "string"
        +}
  4. 6 tool updatesv2.1.0
    • First observedfreeagent_create_expense
    • First observedfreeagent_create_mileage_expense
    • First observedfreeagent_explain_transaction
    • First observedfreeagent_list_bank_accounts
    • First observedfreeagent_list_categories
    • First observedfreeagent_list_transactions

TDQS

A3.7/5.0
Disambiguation4/5

Most tools map cleanly to a specific resource and action, such as invoices, contacts, bills, timeslips, or reports. Minor overlap exists between `freeagent_create_expense` and `freeagent_explain_transaction` because both can attach receipts and match bank transactions, but the descriptions make the primary intent reasonably clear.

Naming Consistency4/5

The server uses a consistent `freeagent_` prefix and mostly follows a verb_resource naming pattern like `list_invoices`, `create_bill`, and `delete_timeslip`. The report tools break the pattern with noun-style names such as `freeagent_profit_and_loss`, `freeagent_trial_balance`, and `freeagent_tax_timeline`, but the deviation is minor and readable.

Tool Count3/5

28 tools is above the comfortable management range, though the FreeAgent domain is broad: invoicing, banking, contacts, expenses, bills, timeslips, tasks, and reporting are all represented. The tools are not redundant or padded, but the overall number is heavy for an agent to scan and select from.

Completeness3/5

The server covers many core workflows, especially invoicing, bank reconciliation, expenses, and financial reporting. However, several resources have incomplete lifecycle coverage: contacts can be created and listed but not updated/deleted, expenses cannot be listed or updated, and invoices can only have their status changed, not their line items or amounts corrected.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Automates FreshBooks invoicing and time tracking through Claude, allowing users to send invoices, list invoices, log billable hours, and get financial insights via natural language commands.
    2
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude to interact with freee accounting software through OAuth 2.0 authentication, supporting operations like transaction creation, account management, receipt uploads, and financial statement retrieval.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables Claude to interact with a Folio business bank account for managing accounts, transactions, receipts, bookkeeping, and payments as drafts.
    14
    22
    5
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Enables Claude Desktop to interact with freee accounting API for expense registration, transaction management, and receipt image processing.
    15
    1
    MIT

Latest Blog Posts

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/OxygenBubbles/freeagent-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server