easybill-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@easybill-mcpShow me the latest unpaid invoices"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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-mcpConfiguration is entirely through environment variables (full list under Configuration). Two matter now:
Leave
EASYBILL_ENABLE_WRITESunset to start read-only.Set
EASYBILL_RATE_LIMIT_PER_MINUTEto 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 |
Cursor |
|
Windsurf |
|
Cline / Roo Code | MCP Servers panel → Configure MCP Servers ( |
Gemini CLI |
|
Claude Code |
|
VS Code / Copilot |
|
Zed |
|
Codex CLI |
|
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-mcpclaude 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-mcpThe 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: datagate-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 buildThen 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-mcpTest 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 smokeIt 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 .envNote:
.envis 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 defaultVerify 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 |
| — | Required. Your easybill API key. |
| unset | Set to |
|
| Client-side throttle. Use |
|
| Max characters per response before truncation. |
|
| HTTP request timeout. |
|
| Retries on HTTP 429 / 5xx. |
| easybill production | Override for a proxy or test double. |
Tools
Customer lookup
Tool | Access |
| 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 |
| read |
| read |
| read — saves PDF / ZUGFeRD / XRechnung to disk |
| read — audit trail |
| write |
| write |
| write — finalises a draft, assigns the invoice number |
| write — creates a STORNO document |
| write — OFFER → INVOICE, INVOICE → DUNNING, … |
| write — sends real email / fax / post |
| 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 askedeasybill_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 (plusid)fields: ["all"]→ every field
Responses over EASYBILL_CHARACTER_LIMIT are truncated, halving the item count until they
fit, and say so in truncation_message.
No fuzzy customer search
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? |
|
Revenue in 2025? |
|
One customer's history |
|
Only real, non-cancelled invoices | add |
Unbilled tracked time |
|
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 accountlive.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 infoMost 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
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityAmaintenanceMCP server for the Lexware Office API that enables management of invoices, contacts, articles, vouchers, and more through the Model Context Protocol.Last updated662736Functional Source , Version 1.1, MIT Future
- AlicenseBqualityCmaintenanceMCP server for the DataGate billing platform API, providing read-only tools to manage customers, invoices, products, agreements, sites, and payments.Last updated13MIT
- Alicense-qualityDmaintenanceMCP server for the Billingo V3 Hungarian invoicing API. Manage invoices, partners, products, spendings, and bank accounts from any MCP client.Last updated14MIT
- Alicense-qualityDmaintenanceMCP server for the Invapi E-Invoicing API, enabling conversion, validation, and extraction of invoices in UBL, CII, ZUGFeRD, Excel, and more.Last updated42MIT
Related MCP Connectors
Hosted MCP server for Mini Accountant: invoices, expenses, customers, analytics, tax estimates.
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Brazilian fiscal MCP server - issue NF-e, NFC-e, NFS-e, CT-e, MDF-e and DC-e via SEFAZ.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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