Skip to main content
Glama

easybill MCP Server

An MCP server for the easybill REST API. Gives any MCP-capable assistant — Claude Code, Claude Desktop, Cursor, VS Code, Windsurf, Zed, Codex CLI, Gemini CLI, Cline — access to your invoices, customers, article catalogue, payments, projects and tracked time.

Built on the official @modelcontextprotocol/sdk (TypeScript), talking stdio.

  • 54 tools across 12 easybill resources

  • Read-only by default — create/update/delete tools stay unregistered unless you opt in

  • Workflow-aware — ships server instructions so the agent resolves the customer before writing a document, instead of guessing where to start

  • Fuzzy customer search the easybill API itself does not offer

  • Self-throttling to respect easybill's 10–60 requests/minute cap

  • Context-aware responses — compact field sets, pagination metadata, automatic truncation


Setup

1. Get an easybill API key

In easybill: Einstellungen → App-Center → API. Create a key and copy it.

2. Register it with your client

This is a plain stdio MCP server published on npm, so any MCP client can run it with npx — no clone, no build, no global install:

npx -y easybill-mcp

Configuration is entirely through environment variables (full list under Configuration). Two matter now:

  • Leave EASYBILL_ENABLE_WRITES unset to start read-only.

  • Set EASYBILL_RATE_LIMIT_PER_MINUTE to 10 on easybill's PLUS plan or 60 on BUSINESS.

Most clients use the same JSON shape under an mcpServers key:

{
  "mcpServers": {
    "easybill": {
      "command": "npx",
      "args": ["-y", "easybill-mcp"],
      "env": {
        "EASYBILL_API_KEY": "your_api_key_here",
        "EASYBILL_RATE_LIMIT_PER_MINUTE": "10"
      }
    }
  }
}

Where that block goes:

Client

Config location

Claude Desktop

Settings → Developer → Edit Config, or ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) · %APPDATA%\Claude\claude_desktop_config.json (Windows)

Cursor

~/.cursor/mcp.json (global) or .cursor/mcp.json (per project)

Windsurf

~/.codeium/windsurf/mcp_config.json

Cline / Roo Code

MCP Servers panel → Configure MCP Servers (cline_mcp_settings.json)

Gemini CLI

~/.gemini/settings.json

Claude Code

claude mcp add, see below

VS Code / Copilot

.vscode/mcp.json, different key — see below

Zed

settings.jsoncontext_servers, see below

Codex CLI

~/.codex/config.toml, TOML instead of JSON — see below

Windows: if a client fails to start npx, use "command": "cmd" with "args": ["/c", "npx", "-y", "easybill-mcp"].

Claude Code

claude mcp add easybill \
  --env EASYBILL_API_KEY=your_api_key_here \
  --env EASYBILL_RATE_LIMIT_PER_MINUTE=10 \
  -- npx -y easybill-mcp

claude mcp add does not overwrite an existing entry — to change the environment later, claude mcp remove easybill -s local first, then add it again.

VS Code (GitHub Copilot agent mode)

VS Code uses servers, not mcpServers, and can prompt for the key instead of storing it in the file. Put this in .vscode/mcp.json (workspace) or open MCP: Open User Configuration:

{
  "inputs": [
    { "id": "easybill_key", "type": "promptString", "description": "easybill API key", "password": true }
  ],
  "servers": {
    "easybill": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "easybill-mcp"],
      "env": {
        "EASYBILL_API_KEY": "${input:easybill_key}",
        "EASYBILL_RATE_LIMIT_PER_MINUTE": "10"
      }
    }
  }
}

Zed

In settings.json:

{
  "context_servers": {
    "easybill": {
      "source": "custom",
      "command": "npx",
      "args": ["-y", "easybill-mcp"],
      "env": {
        "EASYBILL_API_KEY": "your_api_key_here",
        "EASYBILL_RATE_LIMIT_PER_MINUTE": "10"
      }
    }
  }
}

Codex CLI

In ~/.codex/config.toml:

[mcp_servers.easybill]
command = "npx"
args = ["-y", "easybill-mcp"]
env = { EASYBILL_API_KEY = "your_api_key_here", EASYBILL_RATE_LIMIT_PER_MINUTE = "10" }

Hosted clients that only speak remote MCP

Some clients (ChatGPT connectors, hosted agent platforms) accept only HTTP/SSE endpoints, not stdio. Bridge it locally:

npx -y supergateway --stdio "npx -y easybill-mcp"

Only do this if you understand the exposure: anything that reaches that endpoint reaches your accounting data. Keep it bound to localhost or behind a tunnel with authentication, and never run the bridge with writes enabled unless the endpoint is protected.

3. Verify the connection

Ask the assistant to call easybill_get_server_info. It reports the mode, the limits and whether easybill accepted the credentials:

{
  "server_version": "1.0.1",
  "writes_enabled": false,
  "tools_registered": { "read_only": 28, "write": 0, "withheld_because_writes_disabled": 26 },
  "rate_limit_per_minute": 10,
  "connection": "ok — credentials accepted by easybill"
}

4. Enable writes, once you trust it

Add EASYBILL_ENABLE_WRITES=true to the server's environment:

claude mcp add easybill \
  --env EASYBILL_API_KEY=your_api_key_here \
  --env EASYBILL_RATE_LIMIT_PER_MINUTE=10 \
  --env EASYBILL_ENABLE_WRITES=true \
  -- npx -y easybill-mcp

The 26 write tools are registered at startup, so the change only takes effect once the client restarts the server process — editing the config in a running session is not enough. Confirm with easybill_get_server_info: writes_enabled must read true.


Related MCP server: billingo-mcp

Running from a local clone

For development, or to run a version you have not published:

git clone https://github.com/stack74/easybill-mcp.git
cd easybill-mcp
npm install
npm run build

Then point the client at the built entry point instead of npx"command": "node", "args": ["/absolute/path/to/easybill-mcp/dist/index.js"], same env block. Or straight from GitHub without cloning, which is slower because it compiles TypeScript on install via the prepare script and needs a toolchain:

npx -y github:stack74/easybill-mcp

Test locally first

Copy .env.example to .env, put your key in it, then run the read-only self-test:

cp .env.example .env
$EDITOR .env
npm run smoke

It makes five read-only calls and prints what came back:

easybill-mcp-server v1.x.y self-test
API: https://api.easybill.de/rest/v1
Throttle: 60 req/min | writes disabled

  OK    Auth check (customer groups): total=2  first=Stammkunden
  OK    Customers: total=42  first=Example GmbH
  OK    Invoices: total=128  first=RE-2026-0001
  OK    Unpaid invoices: total=7  first=RE-2026-0117
  OK    Articles (positions): total=95  first=ART-001

All probes passed. The server is ready to register with an MCP client.

(Numbers above are illustrative — you will see your own account's totals.)

On a bad key it fails on the first call and stops, so it never burns your rate limit.

To poke at individual tools interactively:

npm run inspect     # MCP Inspector, loads .env

Note: .env is only read by these npm scripts, via Node's --env-file. The server itself reads plain environment variables — when you register it with an MCP client, pass the key through the client's config, not via .env.

Publishing to npm

npm login                  # once, needs an npmjs.com account
npm run build && npm run smoke
npm publish                # unscoped packages are public by default

Verify what ships before you publish — npm pack --dry-run lists the tarball contents. Only dist/, README.md, LICENSE and package.json are included; src/ and .env are not.

For later releases bump the version first (npm version patch|minor|major), which also creates a git tag. npm does not allow republishing an existing version.


Configuration

Variable

Default

Purpose

EASYBILL_API_KEY

Required. Your easybill API key.

EASYBILL_ENABLE_WRITES

unset

Set to true to register create/update/delete tools. Otherwise read-only.

EASYBILL_RATE_LIMIT_PER_MINUTE

60

Client-side throttle. Use 10 for PLUS, 60 for BUSINESS.

EASYBILL_CHARACTER_LIMIT

25000

Max characters per response before truncation.

EASYBILL_TIMEOUT_MS

30000

HTTP request timeout.

EASYBILL_MAX_RETRIES

3

Retries on HTTP 429 / 5xx.

EASYBILL_BASE_URL

easybill production

Override for a proxy or test double.


Tools

Customer lookup

Tool

Access

easybill_find_customer

read — start here: fuzzy search by name, email or number

The easybill API has no full-text search, so this tool tries exact filters first, then pages the customer list and scores candidates locally. It tolerates legal forms (GmbH & Co. KG), punctuation (M.B. MUSTERMANN vs MB Mustermann), umlauts and word order.

Documents — invoices, offers, credit notes, deliveries, orders

Tool

Access

easybill_list_documents

read

easybill_get_document

read

easybill_download_document

read — saves PDF / ZUGFeRD / XRechnung to disk

easybill_list_document_versions

read — audit trail

easybill_create_document

write

easybill_update_document

write

easybill_complete_document

write — finalises a draft, assigns the invoice number

easybill_cancel_document

write — creates a STORNO document

easybill_convert_document

write — OFFER → INVOICE, INVOICE → DUNNING, …

easybill_send_document

write — sends real email / fax / post

easybill_delete_document

write, destructive

Customers, contacts, groups

easybill_list_customers, easybill_get_customer, easybill_create_customer, easybill_update_customer, easybill_delete_customer, easybill_list_contacts, easybill_get_contact, easybill_create_contact, easybill_update_contact, easybill_delete_contact, easybill_list_customer_groups, easybill_get_customer_group

Article catalogue and stock

easybill_list_positions, easybill_get_position, easybill_create_position, easybill_update_position, easybill_delete_position, easybill_list_stock_entries, easybill_get_stock_entry, easybill_create_stock_entry

Payments

easybill_list_document_payments, easybill_get_document_payment, easybill_create_document_payment, easybill_delete_document_payment

Projects and time tracking

easybill_list_projects, easybill_get_project, easybill_create_project, easybill_update_project, easybill_delete_project, easybill_list_time_trackings, easybill_get_time_tracking, easybill_create_time_tracking, easybill_update_time_tracking, easybill_delete_time_tracking

Attachments and templates

easybill_list_attachments, easybill_get_attachment, easybill_download_attachment, easybill_delete_attachment, easybill_list_text_templates, easybill_get_text_template, easybill_list_pdf_templates

Server

easybill_get_server_info — reports mode, limits and whether the credentials work.


Things worth knowing

The server tells the agent how to sequence work

A plain set of endpoint wrappers leads agents astray. Handed an inbound customer inquiry, Claude's first instinct was to call easybill_list_documents — which cannot answer the actual first question, is this company already a customer?

The server therefore ships MCP server instructions (see src/instructions.ts) with the ordering for common tasks, and easybill_create_document opens with the same sequence:

1. easybill_find_customer     — does the customer exist?
2. easybill_create_customer   — only if not
3. easybill_create_document   — creates a DRAFT
4. review with the user
5. easybill_complete_document — assigns the official number, locks it
6. easybill_send_document     — only when explicitly asked

easybill_list_documents explicitly says it is not the tool for orienting yourself. If you extend this server, keep that pattern: state prerequisites at the top of the description of the tool an agent will reach for first.

All money is in cents

easybill represents every monetary value as an integer in cents, even where the API types it as a float. 1999 means 19.99 EUR. This is stated in every tool description that touches an amount, because getting it wrong produces invoices off by 100×.

Times in time tracking (timer_value) are in minutes.

Drafts vs. completed documents

easybill_create_document produces a draft. It has no official document number and can still be edited. Call easybill_complete_document to finalise it — easybill then assigns the number and locks it.

To void a completed invoice, use easybill_cancel_document (which creates a proper STORNO document), not easybill_delete_document. Completed invoices generally cannot be deleted for legal reasons.

Rate limits are low

easybill allows 10 requests/minute on PLUS and 60 on BUSINESS. The server throttles itself to EASYBILL_RATE_LIMIT_PER_MINUTE and, if a 429 slips through, retries while honouring Retry-After. Set the variable to match your plan — otherwise a broad question that pages through many documents will stall.

Because of this, prefer narrow filters over paging: easybill_list_documents with type='INVOICE' and paid_at='null' costs one request, where scanning everything costs dozens.

Context management

Document has 69 fields and Customer 79. List tools therefore return a compact default field set, and single-record lookups return everything. Both accept fields:

  • omit it → compact defaults

  • fields: ["number", "amount"] → just those (plus id)

  • fields: ["all"] → every field

Responses over EASYBILL_CHARACTER_LIMIT are truncated, halving the item count until they fit, and say so in truncation_message.

The easybill API has no full-text search. Customer filters match exact values (each accepts several comma-separated). To find a customer by partial name, either use the exact spelling or page through and match locally.

Useful filter recipes

Question

Call

Which invoices are unpaid?

easybill_list_documents type='INVOICE', paid_at='null'

Revenue in 2025?

easybill_list_documents type='INVOICE', document_date='2025-01-01,2025-12-31'

One customer's history

easybill_list_documents customer_id=<id>

Only real, non-cancelled invoices

add is_draft='0', cancel_id='null'

Unbilled tracked time

easybill_list_time_trackings, then filter cleared_at = null


Development

npm run build      # compile to dist/
npm run typecheck  # tsc --noEmit
npm test           # offline suite — 37 tests, no credentials needed
npm run test:live  # read-only tests against a real account (needs .env)
npm run test:all   # both
npm run dev        # watch mode
npm run smoke      # read-only self-test against the live API (needs .env)
npm run inspect    # MCP Inspector against the built server (needs .env)

Tests

npm test runs offline and needs no easybill account — it covers response shaping, the HTTP client against a mock API, the rate-limit throttle, and the MCP surface (schemas, annotations, write-gating, error handling) driven over the real stdio protocol.

test/
├── helpers/mcp-client.mjs  minimal MCP stdio client + mock API server
├── format.test.mjs         field selection, pagination, truncation, markdown
├── client.test.mjs         auth headers, query serialisation, 429 retry, error mapping
├── rate-limit.test.mjs     sliding-window throttle
├── server.test.mjs         tool registration, workflow guidance, validation, errors
└── live.test.mjs           optional: read-only checks against a real account

live.test.mjs skips itself unless EASYBILL_API_KEY is set, so contributors without an account still get a green suite. It only reads — nothing in the test suite writes to easybill.

Project layout:

src/
├── index.ts              entry point, stdio transport, env validation, --selftest
├── instructions.ts       MCP server instructions: workflow ordering for the agent
├── constants.ts          config, summary field sets, enums
├── schemas/common.ts     shared Zod building blocks
├── services/
│   ├── client.ts         HTTP, auth, throttling, retries, error mapping
│   └── format.ts         field selection, pagination, markdown, truncation
└── tools/
    ├── registry.ts       registration + write-gating
    ├── crud.ts           generic CRUD tool factory
    ├── search.ts         fuzzy customer lookup
    ├── documents.ts      documents + lifecycle actions
    ├── customers.ts      customers, contacts, groups
    ├── catalog.ts        positions, stock
    ├── finance.ts        payments
    ├── work.ts           projects, time tracking
    ├── files.ts          attachments, templates
    └── meta.ts           server info

Most resources are generated from a declarative config in crud.ts; only genuinely resource-specific behaviour (document lifecycle, downloads, sending) is hand-written.

Contributing

Issues and pull requests welcome. The tool surface is derived from easybill's official OpenAPI spec (https://api.easybill.de/rest/v1/swagger.json) — when adding a tool, check field names and types against the spec rather than guessing, and mind that monetary fields are cents even where the spec types them as floats.

Disclaimer

This is an unofficial, community-maintained project. It is not affiliated with, endorsed by, or supported by easybill GmbH. "easybill" is a trademark of its respective owner and is used here only to describe what this software talks to.

The software is provided as-is under the MIT license, without warranty. It can create, modify and delete records in your accounting system, and can send invoices to your customers. You are responsible for what you let it do — start read-only, and review what write tools produce before relying on it.

License

MIT © stack74

Available Tools

28 tools
easybill_download_attachmentDownload attachmentA
Read-onlyIdempotent

Download an attachment's file content and save it to a local path.

Returns the saved file path and size in bytes. The content is NOT loaded into the conversation, so this is safe for large files. Find attachment IDs with easybill_list_attachments.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the attachment to download
output_pathYesAbsolute path to write the file to, e.g. '/Users/me/Desktop/receipt.pdf'. Parent directory must exist.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and destructiveHint, so the bar is lower. The description adds valuable context that content is NOT loaded into the conversation (safe for large files) and that it returns the saved file path and size, which is useful given the lack of an output schema. No contradiction found.

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?

Three sentences: purpose, return value/safety, and pointer to sibling tool. Each sentence earns its place and the key information is front-loaded. No 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 tool with two well-documented parameters, the description covers purpose, return values, safety behavior, and how to obtain required IDs. The absence of an output schema is compensated by explicitly stating what the tool returns. This is fully adequate for an agent to select and invoke 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 coverage is 100% with clear descriptions for both id and output_path. The description does not add meaning beyond the schema—it only restates the concept of saving to a local path. 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 specific action (download an attachment's file content) and destination (save to a local path). It distinguishes from sibling tools by indicating that attachment IDs come from easybill_list_attachments, making the tool's role 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?

Provides clear context: the tool saves locally without loading content into the conversation, making it safe for large files. It also tells users to find attachment IDs via easybill_list_attachments. However, it does not explicitly compare against similar tools like get_attachment, so no explicit alternative/exclusion is given.

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

easybill_download_documentDownload document fileA
Read-onlyIdempotent

Download a document as a PDF or e-invoicing file and save it to a local path.

Supported formats: 'pdf' (plain), 'zugferd1', 'zugferd2_2' (PDF with embedded XML), 'xrechnung2_3', 'xrechnung3_0' (XML), and 'jpg' (first page as an image).

Returns the saved file path and its size in bytes. The file content itself is NOT loaded into the conversation, so this is safe for large PDFs.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the document to download
formatNoFile format to request.pdf
output_pathYesAbsolute path to write the file to, e.g. '/Users/me/Desktop/invoice-123.pdf'. Parent directory must exist.

TDQS

A4.4/5.0
Behavior5/5

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

Beyond annotations (readOnly, idempotent, etc.), the description adds key behavioral details: it returns the saved file path and size, and states that file content is NOT loaded into the conversation, making it safe for large PDFs. This complements the annotations and provides valuable context for the agent.

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 three sentences, front-loaded with the main purpose, and clearly structured. Each sentence earns its place: purpose, formats, and return/safety note. 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?

Given no output schema, the description explains return values (path and size). It covers formats, safety, and behavior. Missing is what happens if the file already exists (overwrite?) or if the directory doesn't exist (schema says parent must exist, but description doesn't mention it in context). Still, it is largely complete for a moderate-complexity tool with good annotations.

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 meaning to the 'format' enum by explaining what each format is (e.g., 'PDF with embedded XML', 'first page as an image'), which goes beyond the bare schema descriptions. It also clarifies the purpose of output_path 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?

The description clearly states the tool downloads a document file to a local path, with specific verb ('Download') and resource ('document'). It lists supported formats and distinguishes from the sibling tool 'easybill_download_attachment' by focusing on documents rather than attachments.

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 (e.g., when you need a PDF or e-invoicing file saved locally) and explains return behavior, but it does not explicitly mention when to use this over alternatives like 'easybill_download_attachment' or provide exclusion criteria. Context is present but no clear when-not-to-use guidance.

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

easybill_find_customerFind a customer by name, email or number (fuzzy)A
Read-onlyIdempotent

Search for an existing customer by company name, person name, email, customer number or city.

USE THIS FIRST whenever you need to know whether someone is already a customer — for example before creating an offer or invoice from an inbound inquiry. The easybill API has no full-text search, so this tool combines exact filters with a local fuzzy match over the customer list.

It tolerates the differences that break exact matching: legal forms ('GmbH & Co. KG'), punctuation ('M.B. MUSTERMANN' vs 'MB Mustermann'), umlauts, and word order.

Args:

  • query (string): what to search for. A company name, surname, email or customer number.

  • limit (number): max candidates to return, 1-25 (default 5).

  • min_score (number): 0-1 match threshold (default 0.5). Lower it to cast a wider net.

  • max_pages (number): how many pages of 1000 customers to scan in the fallback (default 3). Each page is one API request, so keep this low on a plan with a 10 req/min limit.

Returns: { query, match_count, exact_match (boolean), candidates[] } where each candidate has its easybill 'id', 'match_score' (1 = certain) and the usual summary fields.

Next steps based on the result:

  • Exactly one strong candidate (score 1) -> use its 'id' as customer_id.

  • Several candidates -> show them to the user and ask which one, do NOT guess.

  • No candidates -> the customer does not exist yet. Create it with easybill_create_customer, then use the returned 'id'.

Examples:

  • "Is Mustermann Handels GmbH & Co. KG already a customer?" -> query="Mustermann Handels GmbH & Co. KG"

  • "Find the customer with email einkauf@example.com" -> query="einkauf@example.com"

  • "Look up customer number 10023" -> query="10023"

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax candidates to return.
queryYesCompany name, person name, email address, customer number or city.
max_pagesNoPages of 1000 customers to scan in the fuzzy fallback. Each costs 1 request.
min_scoreNoMinimum match score, 0-1. Lower for a wider net.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.8/5.0
Behavior5/5

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

The description richly discloses behavior beyond the readOnly/idempotent annotations: it explains the fuzzy matching process, tolerance for legal forms/punctuation/umlauts/word order, the paginated fallback over 1000-customer pages, and rate-limit implications ('keep this low on a plan with a 10 req/min limit'). It also details the exact return structure and operational next steps, providing full transparency.

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 front-loaded with the essential purpose ('Search for an existing customer...') followed by usage guidance and a well-structured Args/Returns/Examples format. Every sentence earns its place, and the length is justified by the tool's complexity. The structure makes it easy to scan and extract key decision rules.

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 description is highly complete for a complex tool: it explains purpose, usage, fuzzy matching behavior, return shape, and next-step actions even without an output schema. The only notable gap is the undocumented response_format parameter, which could alter the return format despite the 'Returns' section assuming a JSON object. Otherwise, the description covers all critical aspects.

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?

Although the schema covers 100% of parameters, the description adds operational context: min_score is described as a 'match threshold' with advice to 'lower it to cast a wider net'; max_pages notes each page costs one API request; limit is tied to candidate count. However, response_format is absent from the description's Args list despite being in the schema, and its behavioral impact (markdown vs. JSON) is not explained, so the added value is slightly reduced.

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 verb+resource: 'Search for an existing customer by company name, person name, email, customer number or city.' It explicitly distinguishes itself from siblings by stating 'USE THIS FIRST whenever you need to know whether someone is already a customer' and highlighting fuzzy matching capabilities, which list_customers and get_customer lack.

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 gives explicit when-to-use guidance: 'USE THIS FIRST whenever you need to know whether someone is already a customer — for example before creating an offer or invoice.' It also explains why (API has no full-text search) and provides 'Next steps' that dictate when to use this tool vs. creating a new customer, offering clear decision support.

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

easybill_get_attachmentGet attachmentA
Read-onlyIdempotent

Fetch one attachment by its numeric easybill ID, returning all fields by default.

Use easybill_list_attachments first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the attachment
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, and non-destructive behavior, so the description adds value with extra behavioral details: returns all fields by default, supports field narrowing, and clarifies that monetary values are integers in cents. These details help the agent set expectations without contradicting 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?

Three concise sentences, each serving a distinct purpose: the main action, a practical usage hint, and a data-format tip. No redundant or filler text; the description is front-loaded and highly efficient.

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 get-by-ID tool with a well-covered schema and safety annotations, the description provides all necessary context: what it does, how to use it correctly, and important data format caveats. No output schema exists, but the description adequately communicates return behavior (all fields by default) without needing to enumerate them.

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 has 100% parameter coverage with clear descriptions, so a baseline of 3 applies. The description adds meaningful context beyond the schema by noting the default behavior (all fields) and the cents formatting for monetary values, which is not in the schema. This enhances parameter understanding.

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 fetches a single attachment by numeric easybill ID, using a specific verb and resource. It distinguishes itself from sibling tools like list_attachments (listing) and download_attachment (downloading content) by focusing on retrieving a single attachment's metadata/fields.

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 instructs to use easybill_list_attachments when only a name or number is known, providing a clear alternative. Also explains how to narrow the response with the 'fields' parameter, giving practical usage guidance beyond the schema.

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

easybill_get_contactGet contactA
Read-onlyIdempotent

Fetch one contact by its numeric easybill ID, returning all fields by default.

Use easybill_list_contacts first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the contact
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
customer_idYesThe numeric ID of the customer whose contacts these are. Find it with easybill_list_customers.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds useful context beyond that: monetary values are integers in cents and the default field behavior. However, it contradicts the schema's claim that omitting 'fields' gives a compact default set, which slightly undermines transparency.

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?

Three concise sentences, front-loaded with the primary action. Each sentence earns its place: the first states purpose and default behavior, the second gives an alternative usage path, and the third provides parameter narrowing and a unit caveat. 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 simple get-by-ID operation, the description covers main usage, alternative, field narrowing, and the key monetary unit detail. The schema richly documents the parameters. Gaps include missing an explicit note that customer_id is required and the fields default contradiction, but overall it is adequate for a tool with this complexity.

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%, so the baseline is 3. The description adds some value by noting the cents convention and explicitly saying to pass 'fields' to narrow the response, but it also conflicts with the schema's field default description. It does not significantly extend the parameter semantics 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 opens with 'Fetch one contact by its numeric easybill ID', a specific verb+resource+identifier that clearly distinguishes this from list tools. The explicit pointer to easybill_list_contacts for name/number lookup reinforces the single-item retrieval purpose.

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 names easybill_list_contacts as the alternative when only a name or number is known, implying use this tool when you have the numeric ID. It also provides guidance on narrowing response fields, which helps the agent choose the right invocation.

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

easybill_get_customerGet customerA
Read-onlyIdempotent

Fetch one customer by its numeric easybill ID, returning all fields by default.

Use easybill_list_customers first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the customer
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare read-only and idempotent hints. The description adds useful behavioral details: 'returning all fields by default' and 'Monetary values are integers in cents (150 = 1.50 EUR)', which are not present in the annotations. 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?

Three concise sentences: the first states the core purpose, the second provides an alternative, and the third gives a parameter tip and a data format warning. No extraneous content; front-loaded with the most important 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 get-by-id tool, the description covers when to use, the default return behavior, and a key data format detail. With no output schema, the monetary unit clarification is valuable. It could mention response_format or error cases, but the schema covers the former and the tool is straightforward.

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 covers 100% of parameters, so baseline is 3. The description does not add significant parameter semantics beyond the schema; it only repeats the 'fields' narrowing concept. The monetary value hint is about return data, not 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 states 'Fetch one customer by its numeric easybill ID' with a specific verb, resource, and method. It distinguishes itself from siblings by noting that easybill_list_customers should be used when only a name or number is known.

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 says 'Use easybill_list_customers first if you only know a name or number', giving an alternative for different lookup scenarios. Also advises using 'fields' to narrow the response, providing clear usage context.

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

easybill_get_customer_groupGet customer groupA
Read-onlyIdempotent

Fetch one customer group by its numeric easybill ID, returning all fields by default.

Use easybill_list_customer_groups first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the customer group
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds useful behavioral details: 'returning all fields by default' and 'Monetary values are integers in cents', which are not implicit. 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?

Three sentences, each focused: purpose, alternative usage, and parameter/data note. No redundant wording or fluff; the description is front-loaded and efficient.

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 tool's simplicity (one required parameter) and complete schema coverage, the description adequately covers the return behavior and data format. No output schema, but the description provides enough context about what is returned. Missing minor details like error handling, but not essential for this read-only tool.

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% description coverage for all three parameters, so the baseline is 3. The description's mention of 'fields' and cents adds minimal new semantic value beyond the schema's parameter 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 'Fetch one customer group by its numeric easybill ID', specifying the action, resource, and identifier. It distinguishes itself from list_customer_groups (which lists) and get_customer (different resource).

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 instructs to use easybill_list_customer_groups first when only a name or number is known, naming the alternative tool directly. Also advises using the 'fields' parameter to narrow the response, giving practical usage context.

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

easybill_get_documentGet documentA
Read-onlyIdempotent

Fetch one document by its numeric easybill ID, returning all fields by default.

Use easybill_list_documents first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the document
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already cover readOnly, idempotent, and non-destructive behavior. The description adds useful context about returning all fields by default and the monetary integer format, which goes beyond 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?

Three concise, front-loaded sentences, each providing distinct value: identification method, fallback guidance, and response customization. No superfluous text.

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 get operation with good annotations and a compact schema, the description covers the essential usage, alternative lookup, field selection, and data format, making it fully self-contained.

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 all parameters described. The description restates the 'fields' narrowing behavior but adds no new parameter-specific details, so it meets 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 states 'Fetch one document by its numeric easybill ID', specifying the verb and resource. It also distinguishes from siblings by directing users to easybill_list_documents when only a name or number is known.

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 provides an alternative: 'Use easybill_list_documents first if you only know a name or number.' This gives clear when-to-use vs when-not-to-use guidance, exceeding the baseline.

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

easybill_get_document_paymentGet document paymentA
Read-onlyIdempotent

Fetch one document payment by its numeric easybill ID, returning all fields by default.

Use easybill_list_document_payments first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the document payment
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.2/5.0
Behavior4/5

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

With annotations already declaring read-only, idempotent, non-destructive behavior, the description adds valuable context: returning all fields by default and monetary values in cents. This goes beyond annotations and helps set expectations for the response format and units.

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?

Three sentences, front-loaded with purpose, followed by alternative usage and a key data-format note. Every sentence contributes value without redundancy, making it efficient and easy to scan.

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 get-by-ID operation, the description is complete: it states the input, default behavior, optional narrowing, and an important monetary unit detail. The lack of an output schema is mitigated by the default-return statement, though it doesn't enumerate exact return fields beyond 'all fields by default'.

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 provides 100% coverage with detailed descriptions for all three parameters, including the 'fields' array and response_format enum. The description's 'Pass fields to narrow the response' reinforces but doesn't add new parameter semantics; the cents note is about return data rather than 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 clearly states the tool fetches one document payment by its numeric easybill ID, with a specific verb and resource. It distinguishes itself from sibling tools like easybill_list_document_payments by emphasizing 'one' vs. listing.

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 explicitly advises using easybill_list_document_payments when only a name or number is known, providing a clear alternative for a specific condition. While it doesn't exhaustively list all exclusions, it gives practical guidance for when to use this getter vs. the list counterpart.

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

easybill_get_positionGet positionA
Read-onlyIdempotent

Fetch one position by its numeric easybill ID, returning all fields by default.

Use easybill_list_positions first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the position
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4/5.0
Behavior3/5

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

The annotations already declare readOnlyHint, idempotentHint, and destructiveHint as false, covering the safety profile. The description adds useful behavioral detail about default field selection (though inaccurately) and the cent-based interpretation of monetary values. However, it claims 'returning all fields by default' while the input schema for the 'fields' parameter says 'Omit for a compact default set', creating a direct contradiction in behavior disclosure.

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?

The description is concise at three sentences, with no fluff or redundant filler. Each sentence serves a distinct purpose: primary action, usage alternative, and parameter/data note. However, the inaccurate claim about default fields slightly reduces the overall quality since one sentence contains misleading 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 relatively simple read operation, the description covers the essential aspects: the core action, a clear alternative workflow, the fields parameter behavior, and the cent-based monetary format. It does not describe error cases, but given the available annotations and a small parameter set, the description is mostly complete. The only significant gap is the aforementioned default-fields contradiction, which leaves a factual gap in expected behavior.

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 the baseline is 3. The description does add the monetary-unit note (150 = 1.50 EUR), which is relevant for interpreting amounts. However, it also contradicts the schema's own parameter description for 'fields': the tool description says 'returning all fields by default' but the schema says omitting fields returns a compact default set. This inconsistency undermines parameter clarity and reduces the value added 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 opens with 'Fetch one position by its numeric easybill ID', using the specific verb 'Fetch' and clearly scoping the resource to a single position by ID. It also differentiates from the sibling tool easybill_list_positions by indicating that the list tool should be used when only a name or number is known, so the purpose is unambiguous and well-distinguished.

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 explicitly provides a when-not-to-use instruction: 'Use easybill_list_positions first if you only know a name or number.' This names the alternative tool and clarifies the condition for using this get-by-ID tool instead. It also gives guidance on using the 'fields' parameter to narrow the response, which is practical for invocation.

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

easybill_get_projectGet projectA
Read-onlyIdempotent

Fetch one project by its numeric easybill ID, returning all fields by default.

Use easybill_list_projects first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the project
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A3.8/5.0
Behavior2/5

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

While annotations already declare readOnly and idempotent hints, the description adds 'returning all fields by default' which directly contradicts the schema's statement that omitting 'fields' yields a 'compact default set.' This is a factual misrepresentation of the tool's behavior. The monetary unit note is useful, but the misleading default undermines transparency.

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 three short sentences: a clear purpose statement, a usage tip, and a unit note. It is front-loaded with the core action and every sentence earns its place with no redundancy or fluff.

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?

The description covers the typical list-then-get flow, field narrowing, and monetary unit clarification. However, the incorrect default-set claim leaves a significant gap in understanding the actual response behavior. No mention of error cases, but that is acceptable given the tool's simplicity and annotations.

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 coverage is 100% with detailed parameter descriptions, so the baseline is 3. However, the description's claim about 'all fields by default' conflicts with the schema's 'compact default set,' making its guidance on the fields parameter misleading rather than helpful. It adds no meaningful semantic value 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 'Fetch one project by its numeric easybill ID' with a specific verb, resource, and scope. This distinguishes it from list_projects and other sibling tools. It also previews the fields parameter, though the 'all fields' claim is later contradicted by 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 Guidelines5/5

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

Explicitly advises using easybill_list_projects first when only a name or number is known, providing a clear alternative for a different lookup context. Also instructs to pass 'fields' to narrow the response, which gives concrete usage guidance beyond just the schema.

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

easybill_get_server_infoGet server info and connection statusA
Read-onlyIdempotent

Report this MCP server's configuration and verify the easybill API credentials work.

Call this when a write tool appears to be missing, when you get authentication errors, or when you hit rate limits — it explains the current mode and limits.

Returns: { server_version, api_base_url, writes_enabled, tools_registered, rate_limit_per_minute, character_limit, connection } where 'connection' reports whether a live test call to easybill succeeded.

ParametersJSON Schema
NameRequiredDescriptionDefault
test_connectionNoMake one lightweight API call to verify the credentials. Costs one request against your rate limit.

TDQS

A4.7/5.0
Behavior5/5

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

The description goes beyond the annotations (readOnlyHint, idempotentHint, etc.) by explaining that the tool performs a live test call to verify credentials, that the test_connection parameter costs one request against the rate limit, and that the 'connection' field reports success. This adds operational context not present in structured fields.

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 and well-organized: a one-sentence purpose, a one-sentence usage trigger, and a clear return-field list. 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.

Completeness5/5

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

Despite having no output schema, the description explicitly enumerates the return fields (server_version, api_base_url, writes_enabled, etc.) and explains the meaning of 'connection'. Combined with strong annotations and clear usage guidance, the tool is fully understood without additional context.

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 is fully documented in the input schema ('Make one lightweight API call to verify the credentials. Costs one request against your rate limit.'), so the description adds little beyond what the schema already provides. The schema coverage is 100%, 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 uses a specific verb ('report') and resource ('this MCP server's configuration and verify the easybill API credentials'), clearly distinguishing it from sibling tools that focus on listing or retrieving business objects. It explicitly states what the tool does, leaving no ambiguity.

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 second sentence provides explicit, actionable triggers: 'Call this when a write tool appears to be missing, when you get authentication errors, or when you hit rate limits.' This is direct when-to-use guidance tailored to common agent failure modes, and no alternatives are needed since the tool is unique.

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

easybill_get_stock_entryGet stock entryA
Read-onlyIdempotent

Fetch one stock entry by its numeric easybill ID, returning all fields by default.

Use easybill_list_stock_entries first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the stock entry
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already declare the tool as read-only, idempotent, and non-destructive, so the description does not need to restate that. It adds valuable behavioral context: returns all fields by default, allows narrowing via 'fields', and crucially discloses that monetary values are integers in cents (150 = 1.50 EUR). This goes beyond annotations and helps prevent misinterpretation.

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 four sentences, each earning its place: purpose, usage guideline, field-narrowing tip, and currency caveat. It is front-loaded with the primary action and contains no redundant information.

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 tool with good schema coverage and no output schema, the description is complete. It explains what the tool does, when to use it, how to filter fields, and highlights a critical unit conversion. It also directs the user to the sibling list tool when appropriate, ensuring the agent has enough context to select 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?

The input schema already covers all three parameters with descriptions, so the baseline is 3. The description adds extra meaning by explaining the effect of the 'fields' parameter ('narrow the response') and the cost implication ('Fewer fields = less context used'). It also provides the important units for monetary values, which influences how parameters and responses should be interpreted.

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 fetches one stock entry by its numeric ID, which is a specific verb+resource. It explicitly distinguishes itself from the sibling list tool by stating that list should be used first if only a name or number is known.

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 direct usage guidance: use this tool when you have the numeric easybill ID, and use easybill_list_stock_entries first if you only know a name or number. It also explains how to use the 'fields' parameter to narrow the response, which is actionable.

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

easybill_get_text_templateGet text templateA
Read-onlyIdempotent

Fetch one text template by its numeric easybill ID, returning all fields by default.

Use easybill_list_text_templates first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the text template
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint and idempotentHint, so the description doesn't need to re-explain safety. It adds useful context about monetary values in cents and default field behavior, but the claim 'returning all fields by default' contradicts the schema's 'Omit for a compact default set', undermining trust in the disclosed behavior.

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 description is short and front-loaded, but the first sentence contains an inaccurate statement about default fields. A sentence that misleads does not earn its place, so despite efficient structure, it loses points for not being reliable.

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?

The description covers the key action, a necessary alternative, and the cents convention. However, it lacks error behavior (e.g., what happens if ID not found) and the default-field contradiction leaves the return format ambiguous. Given no output schema, more completeness would be expected.

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 coverage is 100%, so baseline is 3. The description adds only marginal value (e.g., 'Pass fields to narrow the response') but also misstates that the default returns all fields, which conflicts with the schema's compact default set. This misleading extra information worsens parameter understanding rather than improving it.

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 'Fetch one text template by its numeric easybill ID' with a specific verb, resource, and identifier. It distinguishes from the sibling list tool by recommending easybill_list_text_templates when only a name/number is known, making the tool's purpose unmistakable.

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 says 'Use easybill_list_text_templates first if you only know a name or number', providing a clear when-to-use alternative. It also instructs to 'Pass fields to narrow the response', giving direct parameter usage guidance.

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

easybill_get_time_trackingGet time tracking entryA
Read-onlyIdempotent

Fetch one time tracking entry by its numeric easybill ID, returning all fields by default.

Use easybill_list_time_trackings first if you only know a name or number. Pass 'fields' to narrow the response. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the time tracking entry
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare this as read-only, idempotent, and non-destructive. The description adds valuable behavioral context: returns all fields by default, fields can narrow the response, and monetary values are integer cents. This goes beyond what annotations provide 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?

Three well-structured sentences: first states the primary action, second gives critical usage guidance, third notes a key data format detail. No wasted words, and the most important information is front-loaded.

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 single-entry fetch with rich annotations and full schema coverage, the description is largely complete. It clarifies return behavior ('all fields by default'), field narrowing, and monetary handling. Slight gaps include response structure details, but that is acceptable given no output schema and the tool's simplicity.

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 three parameters with detailed descriptions, so the schema handles the heavy lifting. The description adds minimal extra parameter meaning beyond restating that 'fields' narrows the response, but the schema already says this. 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 uses the specific verb 'Fetch' with the resource 'one time tracking entry' and clarifies the key identifier 'numeric easybill ID'. It clearly distinguishes this from the sibling list tool by emphasizing single-entry retrieval.

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 directs users to use easybill_list_time_trackings first if only a name or number is known, naming the alternative tool. Also provides guidance on using the 'fields' parameter to narrow the response, covering the main decision point.

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

easybill_list_attachmentsList attachmentsA
Read-onlyIdempotent

List attachments from easybill with optional filters and pagination.

Files stored in easybill and linked to a document, customer or project. This endpoint has no filters — page through the list and match on 'document_id', 'customer_id' or 'file_name'. Use easybill_download_attachment to fetch the actual file content.

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the readOnly annotations, the description discloses key behavioral traits: no server-side filtering, pagination structure, compact vs. full field set, and that monetary values are integer cents. This goes well beyond the structured annotations and prepares the agent for response handling.

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?

The description is organized into short paragraphs with clear topics (listing, filtering, download alternative, fields, return format, paging, monetary values). Each sentence carries information, but the contradictory 'optional filters' vs 'no filters' is an unnecessary redundancy that wastes a small amount of space.

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 no output schema, the description fully compensates by specifying the exact return shape ({ total, count, page, pages, has_more, next_page, items[] }) and how to use it. It also covers param nuances, paging, currency, and links to sibling tools, making it complete for a 4-parameter listing tool.

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%, but the description adds meaningful context beyond the schema: explains the tradeoff of selecting fields ('Fewer fields = less context used'), clarifies the 'fields' array usage with ['all'], and emphasizes using 'next_page' for continuation. This adds value, though the schema already defines parameter basics.

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 lists attachments from easybill and differentiates from download_attachment. However, the opening sentence mentions 'optional filters' while the second paragraph says 'This endpoint has no filters', creating internal contradiction that slightly muddles the purpose.

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 the use case ('page through the list and match on document_id, customer_id or file_name') and names the alternative tool for fetching file content (easybill_download_attachment). Also gives pagination guidance via 'next_page' and field selection advice, leaving no ambiguity about when to use this tool.

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

easybill_list_contactsList contactsA
Read-onlyIdempotent

List contacts from easybill with optional filters and pagination.

Contacts are always scoped to one customer, so 'customer_id' is required.

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
customer_idYesThe numeric ID of the customer whose contacts these are. Find it with easybill_list_customers.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint, idempotentHint, destructiveHint), the description discloses useful behavioral details: returns a compact field set by default, the fields parameter can request ['all'], the exact pagination response shape, and the fact that monetary values are integers in cents. This adds significant value 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?

The description is concise and well-structured: it opens with the core purpose, then the key prerequisite, and finally the return format and pagination hints. Every sentence adds value, with 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?

Given there is no output schema, the description does a great job explaining the return shape, pagination, and data format. It covers the required parameter (customer_id), pagination, fields selection, and monetary units, making it sufficiently complete for an agent to use 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?

Schema description coverage is 100%, so the schema already documents each parameter well. The description adds extra meaning by explaining the compact default field set, the use of ['all'], and the cents-based monetary values, which are not in the schema. The 'optional filters' mention is slightly misleading but does not heavily impact parameter understanding.

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 contacts from easybill' with a specific verb and resource, and it distinguishes itself from the sibling 'easybill_get_contact' by focusing on listing rather than retrieving a single contact. It also adds essential scope information: 'Contacts are always scoped to one customer, so customer_id is required.'

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 on when to use the tool: it requires a customer_id and explains pagination via next_page. However, it does not explicitly mention alternatives like easybill_get_contact for fetching a single contact, and the phrase 'optional filters' is somewhat vague since the schema includes no actual filter parameters beyond pagination/projection.

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

easybill_list_customer_groupsList customer groupsA
Read-onlyIdempotent

List customer groups from easybill with optional filters and pagination.

Customer groups classify customers and can carry their own pricing level. Use a group's 'id' as 'group_id' when creating or filtering customers.

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already indicate a safe, read-only, idempotent operation. The description adds useful behavior details like default compact fields, response structure, and monetary cents. However, it misleadingly states 'optional filters' when no filter parameters exist in the schema, which misrepresents the tool's actual behavior and reduces transparency.

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?

The description is reasonably concise at about 120 words and well-structured with separate paragraphs for purpose, context, return format, and currency. Each sentence carries useful information, though the misleading 'optional filters' phrase adds unnecessary and inaccurate wording. Overall, it is efficient without being terse.

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?

Without an output schema, the description explicitly lists the response structure and explains pagination via 'next_page', which is essential. It also covers the fields parameter and currency format. However, the false claim of 'optional filters' creates a gap, as the description does not clarify that no filtering is supported, making it slightly incomplete.

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 detailed descriptions for all four parameters, so the description does not need to add much. It does mention 'pass fields for specific columns or all' and 'use next_page to continue', but these are largely redundant with the schema. The added note about monetary values concerns return data, not parameter semantics.

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 core purpose is clear: 'List customer groups from easybill' with a specific verb and resource. It distinguishes from the sibling 'easybill_get_customer_group' by implying a plural list operation. However, the claim of 'optional filters' is unsupported by the input schema, which slightly muddies the purpose by suggesting filtering capabilities that do not exist.

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 on when to use the tool: customer groups classify customers and their IDs are used as 'group_id' when creating/filtering customers, implying you should call this to get those IDs. It also gives pagination guidance ('Use next_page to continue paging'). It does not explicitly compare with alternatives, but the list-vs-get sibling relationship is clear.

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

easybill_list_customersList customersA
Read-onlyIdempotent

List customers from easybill with optional filters and pagination.

NOTE: easybill has no fuzzy full-text customer search. The filters below match exact values (though each accepts several comma-separated values). To find a customer by a partial name, filter on company_name or last_name with the exact spelling, or page through the list and match locally.

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
emailsNoFilter by email address. Accepts one value or a list of values.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
numberNoFilter by your customer number. Accepts one value or a list of values.
countryNoFilter by country (ISO 2-letter code, e.g. 'DE' or 'DE,AT,CH'). Accepts one value or a list of values.
group_idNoFilter by customer group ID. Accepts one value or a list of values.
zip_codeNoFilter by postal code. Accepts one value or a list of values.
last_nameNoFilter by exact last name. Accepts one value or a list of values.
created_atNoFilter by creation date. Single date 'YYYY-MM-DD' or an inclusive range 'YYYY-MM-DD,YYYY-MM-DD'
first_nameNoFilter by exact first name. Accepts one value or a list of values.
company_nameNoFilter by exact company name. Accepts one value or a list of values.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown
additional_group_idNoFilter by an additional customer group ID. Accepts one value or a list of values.

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the readOnlyHint/idempotentHint annotations, the description reveals important behavior: filters match exact values, returns a compact field set by default, monetary values are integers in cents, and pagination uses 'next_page'. This is substantial added context about how the tool behaves.

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 well-structured, leading with purpose, followed by a brief note on limitations, then output format and response structure. Each sentence adds essential information without redundancy, making it both concise and highly informative.

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 list tool with 14 parameters and no output schema, the description covers return structure, pagination, default fields, and the exact-match behavior, which are all critical. It also preempts confusion with the fuzzy-search note, making it complete for the tool's complexity.

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 description coverage is 100%, so parameters are documented. The description adds extra value by explaining that all filters match exact values (including comma-separated inputs), and clarifies the 'fields' parameter's effect on output. This goes beyond the schema's individual property 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 'List customers' with the resource 'from easybill' and notes optional filters and pagination. This distinguishes it from sibling tools like get_customer or find_customer, and the NOTE adds meaningful scope by clarifying there is no fuzzy search.

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 warns that 'easybill has no fuzzy full-text customer search' and instructs users to filter on partial names via exact spelling or page through the list, effectively explaining when to use this tool and how to work around its limitations. This is clear usage guidance with alternatives.

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

easybill_list_document_paymentsList document paymentsA
Read-onlyIdempotent

List document payments from easybill with optional filters and pagination.

Payments booked against documents. Recording a payment is what marks an invoice as paid — it updates the document's 'paid_amount' and 'paid_at'. To find open invoices instead, use easybill_list_documents with type='INVOICE' and paid_at='null'. Amounts are integers in cents (150 = 1.50 EUR).

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
referenceNoFilter by bank reference / transaction ID. Accepts one value or a list of values.
payment_atNoFilter by payment date. Single date 'YYYY-MM-DD' or an inclusive range 'YYYY-MM-DD,YYYY-MM-DD'
document_idNoFilter by the document (invoice) the payment belongs to. Accepts one value or a list of values.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.6/5.0
Behavior5/5

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

Despite annotations already declaring readOnlyHint, openWorldHint, and idempotentHint, the description adds meaningful context: it explains the side-effect of recording a payment (updates paid_amount/paid_at), the compact default field set, the return structure, and that monetary values are integers in cents. This goes beyond the annotations without contradicting them, giving the agent a realistic model of what the tool does and what the response looks like.

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?

The description is front-loaded with the primary action and structured in clear paragraphs. However, it repeats 'Amounts are integers in cents (150 = 1.50 EUR)' twice, which is redundant and slightly hurts conciseness. Overall it's well-organized and succinct enough for a 7-parameter tool.

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 list tool with 7 optional parameters and no output schema, the description is complete. It specifies the exact return structure ({ total, count, page, pages, has_more, next_page, items[] }), explains pagination, field selection, and provides domain context about payments and invoices. The absence of an output schema is compensated by a concrete return shape, making the tool's behavior predictable.

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 has 100% coverage with clear descriptions for every parameter, so the baseline is 3. The description adds little that isn't already in the schema: it restates the fields option and mentions 'next_page' for pagination, both of which appear in the schema descriptions. The 'cents' note applies to returned data, not input params. Thus the description does not significantly enhance parameter understanding 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 opens with 'List document payments from easybill with optional filters and pagination' — a specific verb and resource. It further clarifies the domain concept ('Payments booked against documents. Recording a payment is what marks an invoice as paid...') and differentiates from the sibling tool easybill_list_documents by pointing to the alternative for open invoices. This makes the tool's purpose unmistakable.

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 explicitly directs users: 'To find open invoices instead, use easybill_list_documents with type='INVOICE' and paid_at='null'.' This is a clear when-to-use vs. alternative statement. It also explains pagination behavior ('Use 'next_page' to continue paging') and field-selection options, making the usage context concrete.

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

easybill_list_documentsList documentsA
Read-onlyIdempotent

List documents from easybill with optional filters and pagination.

Covers every document type: invoices, offers, credit notes, reminders, deliveries, orders.

NOT the right tool for: finding out whether a customer exists (use easybill_find_customer), or orienting yourself before creating a document (see easybill_create_document). Only call this when you actually need to read existing documents, and always with a filter.

Common recipes:

  • Unpaid invoices: type='INVOICE', paid_at='null'

  • Revenue in a period: type='INVOICE', document_date='2025-01-01,2025-12-31'

  • A customer's history: customer_id=

  • Exclude drafts: is_draft='0' - exclude cancelled: cancel_id='null'

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
typeNoFilter by document type. One of INVOICE, RECURRING, CREDIT, OFFER, REMINDER, DUNNING, STORNO, STORNO_CREDIT, DELIVERY, PDF, CHARGE, CHARGE_CONFIRM, LETTER, ORDER, PROFORMA_INVOICE, STORNO_PROFORMA_INVOICE, or several comma-separated (e.g. 'INVOICE,CREDIT').
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
titleNoFilter by document title.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
numberNoFilter by document number (the official invoice number). Accepts one value or a list of values.
ref_idNoFilter by reference ID.
statusNoFilter by status (ACCEPT, DONE, DROPSHIPPING, CANCEL). Not all types have one.
paid_atNoFilter by payment date. Single date 'YYYY-MM-DD' or an inclusive range 'YYYY-MM-DD,YYYY-MM-DD'. Use the literal string 'null' to find all UNPAID documents.
is_draftNo'0' = only completed documents, '1' = only drafts.
cancel_idNoFilter by the ID of the cancelling document. Use the literal string 'null' for all documents that are NOT cancelled. Accepts one value or a list of values.
edited_atNoFilter by last edit date. Single date 'YYYY-MM-DD' or an inclusive range 'YYYY-MM-DD,YYYY-MM-DD'
is_archiveNo'0' = not archived, '1' = archived only.
project_idNoFilter by project ID. Accepts one value or a list of values.
customer_idNoFilter by customer ID. Accepts one value or a list of values.
vat_countryNoFilter by VAT country (ISO 2-letter code).
document_dateNoFilter by document date. Single date 'YYYY-MM-DD' or an inclusive range 'YYYY-MM-DD,YYYY-MM-DD'
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown
shipping_countryNoFilter by shipping country (ISO code).
fulfillment_countryNoFilter by fulfillment country (ISO code).

TDQS

A4.9/5.0
Behavior5/5

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

Despite annotations already declaring readOnlyHint and idempotentHint, the description adds valuable behavioral details: compact default field set, pagination response shape with next_page, monetary values in cents, and the 'always with a filter' recommendation. This goes well beyond the annotations to explain actual 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 longer than average but every section earns its place: purpose, coverage, exclusions, recipes, return format, and monitoring units. It is well-structured and front-loaded with the core purpose, making it easy to scan.

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 tool with 20 parameters and no output schema, the description is remarkably complete. It explains the response envelope, pagination, default/compact fields, monetary units, and even mentions 'always with a filter' to prevent unbounded queries. This fully equips an agent to invoke the tool 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?

The schema already covers all 20 parameters with detailed descriptions (100% coverage), so the baseline is 3. The description adds extra value through common recipes (e.g., paid_at='null' for unpaid) and guidance on limiting output via the 'fields' parameter to save context, which helps select appropriate parameter values.

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 immediately states 'List documents from easybill with optional filters and pagination', which is a specific verb+resource+scope. It also distinguishes from siblings by covering every document type and explicitly contrasting with easybill_find_customer and easybill_create_document.

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 explicitly says 'NOT the right tool for' customer lookup or pre-creation orientation, and tells when to use it: 'Only call this when you actually need to read existing documents, and always with a filter.' It also provides common recipes for common use cases, giving clear when-to-use and when-not-to-use guidance.

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

easybill_list_document_versionsList document versionsA
Read-onlyIdempotent

List the change history of a document. easybill snapshots a version whenever a completed document is modified, which is what you need for audit questions like 'was this invoice altered after it was issued?'.

Returns: { total, count, page, pages, items[] } with each version's id, created_at and reason.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesThe numeric easybill ID of the document
pageNoPage number, starting at 1.
limitNoItems per page.
response_formatNomarkdown

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare read-only, idempotent, and non-destructive. The description adds valuable context about when versions are snapshotted (on modification of completed documents) and what fields each version contains, going 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?

Two concise sentences plus a return structure line. Front-loads the action and purpose, no redundant words. Every sentence contributes.

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 pagination parameters well-defined in schema, the description covers purpose, return structure, and version semantics. It doesn't discuss error handling or default values, but those are either in schema or not critical for a safe read operation. Lacks explicit mention of pagination defaults, but schema provides them.

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 covers 75% of parameters with descriptions (id, page, limit). The description does not elaborate on parameters, leaving response_format's markdown vs json behavior ambiguous. Given high schema coverage, the baseline is acceptable, but the description adds no parameter-specific value.

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 the change history of a document' with a specific verb and resource. It distinguishes itself from sibling tools like list_documents by focusing on versions of a single document and includes an audit use case that reinforces its unique purpose.

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 ties usage to audit questions ('was this invoice altered after it was issued?'), giving clear context for when to use the tool. It doesn't explicitly name alternatives, but the context implies it's for version history rather than document listing/retrieval, which is clear but not fully explicit.

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

easybill_list_pdf_templatesList PDF templatesA
Read-onlyIdempotent

List the PDF layout templates configured in your easybill account.

Pass a template's 'id' as 'pdf_template' when creating or converting a document to control its layout and language. The built-in values are 'DE' (German, the default) and 'EN' (English); anything custom uses a numeric ID.

Note: this endpoint is not paginated and returns all templates at once.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoFilter by document type, e.g. 'INVOICE' or several comma-separated ('INVOICE,OFFER').
response_formatNomarkdown

TDQS

A4.3/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=true. The description goes beyond these by adding behavioral details: 'this endpoint is not paginated and returns all templates at once.' It also explains built-in id values ('DE', 'EN') and their role as layout/language controls. No contradictions found.

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, front-loaded with the main purpose, and uses three short paragraphs each with a distinct piece of useful information. Every sentence adds value without unnecessary verbosity.

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 relatively simple with two optional parameters and no output schema. The description explains the purpose, the non-pagination behavior, and the relationship to document creation. It does not describe the response structure beyond the built-in id values, which is a minor gap for a list tool.

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 only 50% (only 'type' has a description; 'response_format' lacks one). The description does not explain 'type' or 'response_format' parameters at all, leaving the agent to infer their meaning from the schema's incomplete descriptions. Since coverage is below 50%, the description should compensate but does not.

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 starts with a specific verb and resource: 'List the PDF layout templates configured in your easybill account.' It clearly distinguishes the tool from sibling tools like list_text_templates by naming 'PDF layout templates' and the account 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?

The description provides clear context for when to use this tool: to list available PDF templates for use as 'pdf_template' when creating documents. It also notes that the endpoint is not paginated and returns all templates. However, it does not explicitly name alternatives or state when not to use it.

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

easybill_list_positionsList positionsA
Read-onlyIdempotent

List positions from easybill with optional filters and pagination.

Positions are the reusable article catalogue (products, services and text blocks). Referencing one by 'position_id' in a document line item copies its price and description over. Prices are integers in cents (1999 = 19.99 EUR).

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
typeNoFilter by article type.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
numberNoFilter by exact article number. Accepts one value or a list of values.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds valuable behavioral context: pricing in cents, the effect of referencing position_id in documents, the compact default field set, the response shape, and pagination semantics. This goes well beyond the annotations and gives the agent a clear model of what the tool returns and how it behaves.

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 and well-structured: it starts with the main action, then clarifies domain terms, notes currency convention, explains field selection, and lists the return structure. Every sentence adds value with 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?

Given there is no output schema, the description fully explains the response format including total, count, page, pages, has_more, next_page, and items[]. It also covers pagination continuation, field selection, and the cents convention. This is complete for a list tool with optional filters and pagination, leaving no major gaps for an agent to invoke it successfully.

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%, so the input schema already documents all parameters. The description adds some context (e.g., 'Prices are integers in cents' and 'pass fields for specific columns'), but these are largely restatements or extensions of the schema descriptions. Since the schema does the heavy lifting, a baseline of 3 is appropriate with only marginal added value.

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 positions from easybill with optional filters and pagination' and further defines positions as the 'reusable article catalogue (products, services and text blocks)', which distinguishes this list tool from other list tools like easybill_list_documents or easybill_list_customers. The verb and resource are specific and 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 clearly conveys when to use the tool (to list positions), and provides practical usage guidance like using 'fields' for column selection and 'next_page' for pagination. It does not explicitly name alternative tools (e.g., easybill_get_position) for singular retrieval, but the purpose and context are 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.

easybill_list_projectsList projectsA
Read-onlyIdempotent

List projects from easybill with optional filters and pagination.

Projects group documents and tracked time under a customer engagement, with an optional budget. 'consumed_amount' and 'consumed_time' show progress against 'budget_amount' and 'budget_time' — useful for budget-burn questions. Amounts are integers in cents; times are in minutes.

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
statusNoFilter by project status.
customer_idNoFilter by customer ID. Accepts one value or a list of values.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.2/5.0
Behavior4/5

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

Beyond the readOnlyHint/idempotentHint annotations, the description discloses the return envelope structure, 'next_page' continuation mechanism, default field behavior versus 'fields': ['all'], and unit conventions (amounts in cents, times in minutes). This adds meaningful behavioral context without contradicting any 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?

The description is front-loaded with the core purpose, then logically expands to concept context, field selection, and return format. At about 150 words, it is slightly longer than ideal but every sentence adds useful information with no fluff 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?

Since there is no output schema, the description fully covers the return format ({ total, count, page, pages, has_more, next_page, items[] }), pagination mechanics, and unit semantics. Combined with thorough parameter schema and safety annotations, an agent has all the information needed to invoke this 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?

The input schema has 100% coverage with detailed descriptions for all six parameters, including pagination and field selection. The description largely repeats 'fields' behavior and 'next_page' guidance already present in the schema, so it adds minimal new meaning beyond what the schema provides. Baseline 3 applies due to high schema coverage.

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 projects from easybill with optional filters and pagination.' This is a specific verb+resource combination that distinguishes it from sibling tools listing documents, customers, or time trackings. The mention of filters and pagination adds further precision.

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 context on what projects are ('group documents and tracked time under a customer engagement') and suggests a concrete use case ('useful for budget-burn questions'). It does not explicitly name alternative tools or exclusion conditions, so it falls short of a 5, but the context is clear enough for an agent to decide when to use this tool.

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

easybill_list_stock_entriesList stock entriesA
Read-onlyIdempotent

List stock entries from easybill with optional filters and pagination.

Stock entries are the inventory movement log for articles that have stock management enabled (position.stock = 'YES'). Each entry records a new absolute stock level. Filter by position_id to see one article's history.

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
document_idNoFilter by the document that triggered the movement. Accepts one value or a list of values.
position_idNoFilter by article (position) ID. Accepts one value or a list of values.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.7/5.0
Behavior5/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 substantial behavioral detail beyond that: returns a compact field set by default, the exact pagination response shape, the 'next_page' continuation mechanism, and that monetary values are integers in cents (150 = 1.50 EUR). This is valuable runtime context the agent would otherwise lack.

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 front-loaded with the core purpose in the first sentence. Every subsequent sentence adds distinct information: domain semantics, filter guidance, field selection, return shape, pagination, and unit convention. No filler or redundancy; the length is justified by the tool's richness.

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 moderate complexity, no output schema, and a fully documented input schema, the description is remarkably complete. It covers return structure, pagination flow, default field behavior, and data semantics. The agent has enough information to invoke the tool and interpret results without additional lookups.

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 informative parameter descriptions, so the baseline is 3. The description adds extra meaning by explaining the domain semantics ('Each entry records a new absolute stock level') and the practical effect of position_id filtering ('see one article's history'). It also reinforces how pagination parameters interact with the response.

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 stock entries from easybill with optional filters and pagination', a specific verb+resource statement. It further clarifies the semantic meaning ('inventory movement log') and distinguishes from the singular sibling get_stock_entry via the list orientation. No ambiguity remains.

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 clearly states a key use case ('Filter by position_id to see one article's history') and explains when stock entries exist (articles with stock management enabled). It does not explicitly mention alternatives like get_stock_entry for single records, but the context is clear enough for an agent to select this tool for listing/filtering scenarios.

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

easybill_list_text_templatesList text templatesA
Read-onlyIdempotent

List text templates from easybill with optional filters and pagination.

Reusable text blocks for document headers, footers and notes. Handy for reusing your standard payment terms or closing wording when creating a document.

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds valuable details about pagination via next_page, the default compact field set, and monetary units in cents. The unsupported 'filters' mention is a minor behavioral inaccuracy.

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 well-structured, with an intro, use-case, and return details. Each sentence carries useful information, though the 'filters' phrase is redundant and slightly off-point.

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 compensates by specifying the return object shape and pagination mechanics. It covers the essential operational context, but the vague 'optional filters' promise is unfulfilled and leaves a minor gap.

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 extra meaning to 'fields' by explaining the compact default set and the option to request all columns, plus reinforcing pagination usage. It does not misinterpret the actual parameters despite the 'filters' mention.

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 it lists text templates, distinguishing it from siblings like easybill_get_text_template. However, the claim of 'optional filters' is misleading because no filter parameter exists in the schema, slightly detracting from clarity.

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 useful context by describing text templates as reusable blocks for headers, footers, and notes, with an example use case. It does not explicitly contrast with alternatives or state when not to use it, but the use case is clear.

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

easybill_list_time_trackingsList time tracking entriesA
Read-onlyIdempotent

List time tracking entries from easybill with optional filters and pagination.

Tracked working time, optionally tied to a project and an article. 'timer_value' is the tracked duration in MINUTES and 'hourly_rate' is in cents. 'cleared_at' is set once the entry has been billed — entries with cleared_at = null are still unbilled, which is what you want when preparing an invoice.

Returns a compact field set by default; pass 'fields' for specific columns or ['all'] for everything.

Returns: { total, count, page, pages, has_more, next_page, items[] }. Use 'next_page' to continue paging. Monetary values are integers in cents (150 = 1.50 EUR).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number, starting at 1. Use 'next_page' from a previous response to continue.
limitNoItems per page, 1-1000 (default 25). Keep this small unless you need bulk data.
fieldsNoLimit returned columns to these field names (e.g. ['number','amount','paid_at']). Pass ['all'] for every field. Omit for a compact default set. Fewer fields = less context used.
login_idNoFilter by the easybill login (employee) that tracked the time. Accepts one value or a list of values.
project_idNoFilter by project ID. Accepts one value or a list of values.
date_from_atNoFilter by start date. Single date 'YYYY-MM-DD' or an inclusive range 'YYYY-MM-DD,YYYY-MM-DD'
date_thru_atNoFilter by end date. Single date 'YYYY-MM-DD' or an inclusive range 'YYYY-MM-DD,YYYY-MM-DD'
response_formatNoOutput format: 'markdown' for readable prose, 'json' for machine-readable datamarkdown

TDQS

A4.5/5.0
Behavior5/5

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

The description reveals that 'timer_value' is in minutes, 'hourly_rate' is in cents, and that 'cleared_at' is set once billed (null means unbilled). It also explains the default compact field set, the return envelope structure, and use of 'next_page' for paging. This goes well beyond the readOnly/idempotent 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?

Four sentences, each conveying distinct information: purpose, data units, billing filter, and return format. No redundant wording, and each sentence earns its place.

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?

There is no output schema, so the description provides a return shape and paging details. It covers units, billing state, and default fields, making it self-contained and complete for a list operation.

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?

All 8 parameters are already fully documented in the schema, so the baseline is 3. The description does not add new parameter semantics; it only restates the 'fields' and 'next_page' behavior already covered by 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 opens with 'List time tracking entries from easybill with optional filters and pagination', providing a specific verb and resource. It clearly distinguishes itself from the sibling tool 'easybill_get_time_tracking' by implying a list operation rather than a single fetch.

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 states 'which is what you want when preparing an invoice', giving a concrete use case, and mentions filtering by project/article. It does not explicitly name alternatives like get_time_tracking, but the context is clear enough to infer when this list tool is appropriate.

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. 28 tool updatesv1.0.2
    • First observedeasybill_download_attachment
    • First observedeasybill_download_document
    • First observedeasybill_find_customer
    • First observedeasybill_get_attachment
    • First observedeasybill_get_contact
    • First observedeasybill_get_customer
    • First observedeasybill_get_customer_group
    • First observedeasybill_get_document
    • First observedeasybill_get_document_payment
    • First observedeasybill_get_position
    • First observedeasybill_get_project
    • First observedeasybill_get_server_info
    • First observedeasybill_get_stock_entry
    • First observedeasybill_get_text_template
    • First observedeasybill_get_time_tracking
    • First observedeasybill_list_attachments
    • First observedeasybill_list_contacts
    • First observedeasybill_list_customer_groups
    • First observedeasybill_list_customers
    • First observedeasybill_list_document_payments
    • First observedeasybill_list_document_versions
    • First observedeasybill_list_documents
    • First observedeasybill_list_pdf_templates
    • First observedeasybill_list_positions
    • First observedeasybill_list_projects
    • First observedeasybill_list_stock_entries
    • First observedeasybill_list_text_templates
    • First observedeasybill_list_time_trackings

TDQS

A4/5.0
Disambiguation5/5

Each tool targets a distinct resource and action, with clear list/get/action naming. The only potential overlap between find_customer and list_customers is clearly resolved in the descriptions: find is for fuzzy search, list is for exact filtering. Downloads for documents and attachments are unambiguous.

Naming Consistency5/5

All tools follow the easybill_<verb>_<noun> pattern consistently, using list/get/download/find as verbs. Even get_server_info fits the get_ pattern. No mixed conventions or vague verbs.

Tool Count3/5

With 28 tools, the count exceeds the comfortable range, but it is justifiable given the many distinct resources (customers, documents, projects, etc.) covered by the easybill API. It borders on heavy, but each tool has a clear purpose.

Completeness2/5

The server is read-only but repeatedly references missing write tools like easybill_create_customer and easybill_create_document, creating dead ends for agents. There are no create, update, or delete operations, which is a significant gap for an ERP integration.

Maintenance

ActivityMaintained
ResponsivenessSyncing

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

  • A
    license
    B
    quality
    C
    maintenance
    MCP server for the DataGate billing platform API, providing read-only tools to manage customers, invoices, products, agreements, sites, and payments.
    13
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for the Billingo V3 Hungarian invoicing API. Manage invoices, partners, products, spendings, and bank accounts from any MCP client.
    18
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for the Invapi E-Invoicing API, enabling conversion, validation, and extraction of invoices in UBL, CII, ZUGFeRD, Excel, and more.
    59
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server for the SmartBill Cloud API. It lets an MCP client issue and manage Romanian invoices, proformas and payments, download document PDFs, and read VAT rates, series and stock levels.
    23
    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/stack74/easybill-mcp'

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