easybill REST API를 통해 AI 클라이언트가 송장, 고객, 품목 카탈로그, 결제, 프로젝트 및 기록된 시간을 관리할 수 있게 합니다.
다른 이름 stack74/easybill-mcp
- 스타
- 0
- Tools
- 13
- 다운로드, 30일
- —
- 최신 버전
- —
- 마지막 커밋
- 2026년 11월 12일
- 라이선스
- MIT
easybill MCP란?
easybill은(는) MCP server입니다. easybill REST API를 통해 AI 클라이언트가 송장, 고객, 품목 카탈로그, 결제, 프로젝트 및 기록된 시간을 관리할 수 있게 합니다. 13개 도구를 제공합니다. 예: easybill_find_customer, easybill_list_documents, easybill_get_document.
프로젝트 README에서 생성된 요약
easybill MCP server 정보
easybill-mcp를 사용하면 AI 어시스턴트를 통해 비즈니스 재무 및 고객 데이터를 관리할 수 있습니다. 이 서버는 Claude Desktop, Cursor, Windsurf와 같은 MCP 지원 클라이언트를 easybill REST API에 연결하여 사용자가 송장, 고객, 품목 카탈로그, 결제, 프로젝트 및 기록된 시간을 상호작용할 수 있도록 합니다. npx를 사용하여 stdio를 통해 로컬에서 작동하거나, claude.ai와 같은 원격 클라이언트를 위한 호스팅 모드로 작동하도록 설계되었습니다.
보안을 최우선으로 고려하여 서버는 기본적으로 읽기 전용 모드로 작동합니다. 레코드를 생성, 업데이트 또는 삭제하려면 사용자가 반드시 EASYBILL_ENABLE_WRITES 환경 변수를 설정해야 합니다. 이 서버는 기본 API의 한계를 보완하는 퍼지 고객 검색과 같은 지능형 기능을 포함하며, Professional 및 Premium easybill 플랜의 속도 제한을 준수하기 위해 자체 스로틀링 기능을 갖추고 있습니다. 또한 에이전트가 문서를 작성하기 전에 고객 세부 정보를 먼저 확인하도록 워크플로우 인식 지침을 제공합니다.
활용 사례
- 1송장 및 고객 데이터 조회AI 어시스턴트에게 최근 송장 목록을 나열하거나 회계 기록에서 특정 고객 세부 정보를 찾도록 요청하세요.
- 2퍼지 고객 검색 수행내장된 퍼지 검색 기능을 사용하여 정확한 이름이나 ID를 모르더라도 고객을 찾을 수 있습니다.
- 3관리자 쓰기 작업 활성화쓰기 권한을 활성화하여 AI가 문서를 생성하거나 업데이트할 수 있도록 서버를 구성하세요.
- 4다중 사용자 기업 액세스 관리다양한 직원이 각자의 API 키를 연결할 수 있는 조직 전체를 위한 중앙 커넥터를 설정하세요.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
easybill MCP 설치 방법
형식 확인: 2026년 11월 10일Cursor에 추가Goose에 추가Claude Code에 easybill MCP 설치
$ claude mcp add easybill-mcp -- npx -y easybill-mcpCursor에 easybill MCP 설치
~/.cursor/mcp.json
{
"mcpServers": {
"easybill-mcp": {
"command": "npx",
"args": [
"-y",
"easybill-mcp"
]
}
}
}VS Code에 easybill MCP 설치
.vscode/mcp.json
{
"servers": {
"easybill-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"easybill-mcp"
]
}
}
}VS Code CLI에 easybill MCP 설치
$ code --add-mcp '{"name":"easybill-mcp","type":"stdio","command":"npx","args":["-y","easybill-mcp"]}'Claude Desktop에 easybill MCP 설치
claude_desktop_config.json
{
"mcpServers": {
"easybill-mcp": {
"command": "npx",
"args": [
"-y",
"easybill-mcp"
]
}
}
}Codex에 easybill MCP 설치
$ codex mcp add easybill-mcp -- npx -y easybill-mcpCodex config.toml에 easybill MCP 설치
~/.codex/config.toml
[mcp_servers.easybill-mcp] command = "npx" args = ["-y", "easybill-mcp"]
Gemini CLI에 easybill MCP 설치
$ gemini mcp add -s user easybill-mcp npx -- -y easybill-mcpGemini settings.json에 easybill MCP 설치
~/.gemini/settings.json
{
"mcpServers": {
"easybill-mcp": {
"command": "npx",
"args": [
"-y",
"easybill-mcp"
]
}
}
}easybill MCP 도구 13
README에서 감지됨easybill_find_customereasybill_list_documentseasybill_get_documenteasybill_search_documentseasybill_download_documenteasybill_list_document_versionseasybill_create_documenteasybill_update_documenteasybill_complete_documenteasybill_cancel_documenteasybill_convert_documenteasybill_send_document
| easybill_find_customer | — | |
| easybill_list_documents | — | |
| easybill_get_document | — | |
| easybill_search_documents | — | |
| easybill_download_document | — | |
| easybill_list_document_versions | — | |
| easybill_create_document | — | |
| easybill_update_document | — | |
| easybill_complete_document | — | |
| easybill_cancel_document | — | |
| easybill_convert_document | — | |
| easybill_send_document | — |
도구 13개 모두 보기도구 수 줄이기
easybill_delete_document
| easybill_delete_document | — |
구성
EASYBILL_API_KEYEASYBILL_RATE_LIMIT_PER_MINUTE
| 이름 | 설명 | 유형 |
|---|---|---|
| EASYBILL_API_KEY | — | |
| EASYBILL_RATE_LIMIT_PER_MINUTE | — |
자동 검사
2026년 11월 14일에 실행됨전체 보고서 →자동 검사를 통과했습니다. 이는 보안 감사가 아닙니다. 코드를 직접 읽고 서버에 필요한 최소한의 권한만 부여하십시오. 검사 방식
- 소스 저장소 연결 및 접근 가능stack74/easybill-mcp is public and reachablegithub.com/stack74/easybill-mcp ↗통과
- 패키지가 이 저장소를 소스로 명시easybill-mcp names stack74/easybill-mcp as sourcenpmjs.com/package/easybill-mcp ↗통과
- 빌드 출처(Sigstore 증명)Sigstore attestation for easybill-mcpnpmjs.com/package/easybill-mcp/v/1.2.1#provenance ↗통과
- 오픈 소스 라이선스 (OSI)MITspdx.org/licenses/MIT.html ↗통과
- 최근 1년 내 커밋 또는 릴리스Last commit or release 2026-11-12github.com/stack74/easybill-mcp ↗통과
- OpenSSF Scorecard검사되지 않음
- 패키지 이름이 인기 패키지와 유사하지 않음No popular package one edit away from easybill-mcp통과
- 패키지 및 해당 종속성에 중요한 보안 권고 없음검사되지 않음
- 모델에 대한 숨겨진 지침 없음13 tool descriptions and the README read; no override phrases, credential paths or hidden characters통과
- 파괴적인 도구에 라벨 표시됨No tool named like delete, drop or exec통과
- 원격 엔드포인트가 MCP 핸드셰이크에 응답검사되지 않음
README
GitHub에서 보기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.
- 64 tools across 13 easybill resources (65 in hosted mode)
- 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_WRITESunset to start read-only. - Set
EASYBILL_RATE_LIMIT_PER_MINUTEto 10 on easybill's Professional plan or 60 on Premium (Free and Starter have no API access).
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.json → context_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
For claude.ai and other remote-only clients, run the server in hosted mode (see "Hosted mode" below): one connector for the whole company, each person connects the easybill accounts they use with their personal API key.
For a quick single-user experiment you can instead bridge the stdio server 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.
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:
.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 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.
Hosted mode (claude.ai connector, several easybill accounts)
easybill-mcp --http runs the server as a remote MCP endpoint (Streamable HTTP) for a whole
company:
- Someone adds the connector in claude.ai (or any OAuth-capable MCP client).
- The client opens this server's connect page. It lists the easybill accounts from your tenant configuration; the person clicks Verbinden on each account they have access to and pastes their personal easybill API key (easybill: user icon → Profil und Einstellungen → API Key). The server checks it against easybill before storing it.
- Fertig – zurück zu Claude completes the client's OAuth flow.
Every tool then takes an account argument (easybill_list_accounts shows the status and
hands out a link to connect more accounts or replace a key). Keys are stored AES-GCM encrypted
in SQLite. A key easybill rejects later (regenerated, login removed) is marked and the model
hands out the link to replace it.
This server is the OAuth authorization server for the MCP client (claude.ai); easybill itself
only sees API-key requests. An API key does not say which easybill account it belongs to, so on
the first connection of a tenant the server remembers the account's login IDs (from /logins)
and refuses later keys from a different account, including a key that already belongs to another
configured tenant.
easybill OAuth instead of API keys (EASYBILL_CONNECT_MODE=oauth): people log in at easybill
instead of pasting a key. easybill only allows dynamic client registration for an allowlist of
redirect URIs (claude.ai and similar), so this mode needs an OAuth client issued by easybill for
<EASYBILL_PUBLIC_URL>/connect/callback (EASYBILL_OAUTH_CLIENT_ID / _SECRET).
Tenant configuration
{
"tenants": [
{ "id": "firma-a", "name": "Firma A GmbH", "plan": "PREMIUM", "writes": true },
{ "id": "firma-b", "name": "Firma B GmbH", "plan": "PROFESSIONAL", "writes": false }
]
}
| Field | Meaning |
|---|---|
id |
Slug the model passes as account. |
name |
Shown on the connect page and to the model. |
plan |
PROFESSIONAL (10 req/min) or PREMIUM (60 req/min); the former names PLUS / BUSINESS work too. Free and Starter have no API access. Throttle shared by everyone on the account. Or set rate_limit_per_minute. |
writes |
true registers create/update/delete for this account and requests write scopes from easybill. Default read-only scopes. |
scopes |
Optional override of the easybill OAuth scopes. |
match |
OAuth mode only: { "<claim>": "<value>" } checked against easybill's access-token claims, so a login of the wrong company is refused. The server logs the claims of every new connection. |
Environment
| Variable | Default | Purpose |
|---|---|---|
EASYBILL_PUBLIC_URL |
— | Required. Public https base URL. The connector URL is <this>/mcp. |
EASYBILL_MCP_SECRET |
— | Required. ≥ 32 characters; encrypts stored tokens and signs the browser cookie. Changing it invalidates all connections. |
EASYBILL_TENANTS_FILE / EASYBILL_TENANTS |
— | Required. Path to the tenant JSON, or the JSON inline. |
EASYBILL_DB_PATH |
./data/easybill-mcp.sqlite |
SQLite file. Put it on a persistent volume. |
PORT / HOST |
3000 / 0.0.0.0 |
Listen address. |
EASYBILL_CF_ACCESS_TEAM_DOMAIN / EASYBILL_CF_ACCESS_AUD |
— | Put the connect pages behind Cloudflare Access: team domain (e.g. acme or acme.cloudflareaccess.com) and the Access application's AUD tag. /connect/* then requires a valid Access token, checked by the server itself. |
EASYBILL_ICON_PATH |
— | Path to an .svg, .png or .ico file (e.g. a file mount in your hosting platform). Served as /favicon.ico and /favicon.<ext>, linked from the pages and announced as the MCP server icon. claude.ai shows the domain's favicon next to a custom connector. |
EASYBILL_CONNECT_MODE |
apikey (oauth if a client ID is set) |
How people connect easybill accounts. |
EASYBILL_OAUTH_CLIENT_ID / _SECRET |
— | OAuth mode: the client easybill issued for this server. |
EASYBILL_OAUTH_ISSUER |
https://api.easybill.de |
OAuth mode: easybill's OAuth issuer. |
EASYBILL_MCP_ACCESS_TOKEN_TTL |
3600 |
Lifetime (s) of access tokens issued to MCP clients. |
EASYBILL_MCP_REFRESH_TOKEN_TTL |
7776000 |
Lifetime (s) of refresh tokens issued to MCP clients (90 days). |
Needs Node.js ≥ 22.13 (built-in node:sqlite). The Dockerfile builds a ready image:
docker build -t easybill-mcp .
docker run -p 3000:3000 -v easybill-mcp-data:/data \
-v $PWD/tenants.json:/config/tenants.json:ro \
-e EASYBILL_TENANTS_FILE=/config/tenants.json \
-e EASYBILL_PUBLIC_URL=https://easybill-mcp.example.com \
-e EASYBILL_MCP_SECRET="$(openssl rand -base64 48)" \
easybill-mcp
Cloudflare Zero Trust: protect only the path /connect with an Access application (the
connect pages are opened in a browser). Leave /mcp, /token, /register, /authorize and
/.well-known/* outside Access — claude.ai calls them from its servers and cannot pass an Access
login. Without the connect pages nobody can complete the authorization, so tokens stay out of
reach. Set the two EASYBILL_CF_ACCESS_* variables so the server rejects requests that bypass
Cloudflare (e.g. via the origin IP).
Run it behind TLS (reverse proxy). Then in claude.ai: Settings → Connectors → Add custom
connector with https://easybill-mcp.example.com/mcp (organization admins can add it once for
everyone; each person still connects their own easybill logins).
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 Professional, 60 for Premium. |
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: search customers or suppliers by name, email or number |
Uses easybill's full-text search (one request, archived contacts included) and ranks the hits
locally, tolerating legal forms (GmbH & Co. KG), punctuation (M.B. MUSTERMANN vs
MB Mustermann), umlauts and word order. If the search endpoint is unavailable it falls back to
exact filters plus a local scan of the customer list.
Documents — invoices, offers, credit notes, deliveries, orders
| Tool | Access |
|---|---|
easybill_list_documents |
read |
easybill_get_document |
read |
easybill_search_documents |
read — full-text search by word, name or number |
easybill_download_document |
read — PDF, image, ZUGFeRD 1.0–2.5, XRechnung (to disk locally, inline when hosted) |
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
Incoming documents (Eingangsbelege)
easybill_list_incoming_documents, easybill_search_incoming_documents,
easybill_get_incoming_document, easybill_list_incoming_document_files,
easybill_download_incoming_document_file (read);
easybill_upload_incoming_document, easybill_update_incoming_document,
easybill_complete_incoming_document, easybill_delete_incoming_document (write).
Uploads are extracted by easybill in the background; the tools guide the agent through review → correction → completion.
Server
easybill_get_server_info — reports mode, limits and whether the credentials work.
In hosted mode also easybill_list_accounts — connected accounts and the link to connect more.
Files in hosted mode: downloads come back inside the tool result and uploads take base64 — the server never reads or writes caller-chosen paths on its own disk.
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 Professional and 60 on Premium (formerly PLUS and 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.
Full-text search vs. filters
List filters match exact values (each accepts several comma-separated). For a partial name,
a word or a topic use the full-text tools (API 1.102+): easybill_find_customer,
easybill_search_documents, easybill_search_incoming_documents. Each costs one request.
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)
easybill MCP 질문
easybill MCP를 Claude Code에 추가하려면 어떻게 하나요?
터미널에서 claude mcp add easybill-mcp -- npx -y easybill-mcp를 실행합니다. 모든 프로젝트에서 사용할 수 있게 하려면 --scope user를 추가합니다.
easybill MCP를 Cursor에 추가하려면 어떻게 하나요?
~/.cursor/mcp.json를 열고 mcpServers 아래에 서버를 추가합니다. 위 설치 섹션에 표시된 Cursor 구성을 사용합니다.
easybill MCP는 어떤 도구를 제공하나요?
13개 도구를 제공합니다. 예: easybill_find_customer, easybill_list_documents, easybill_get_document, easybill_search_documents, easybill_download_document.
기본적으로 서버는 읽기 전용인가요?
네, EASYBILL_ENABLE_WRITES 환경 변수를 설정하여 명시적으로 허용하지 않는 한 생성, 업데이트, 삭제 도구는 등록되지 않습니다.
저장소를 클론하지 않고 서버를 실행하려면 어떻게 하나요?
npx를 사용하면 수동으로 클론하거나 빌드할 필요 없이 바로 실행할 수 있습니다.
서버에서 퍼지(fuzzy) 고객 검색을 지원하나요?
네, easybill API 자체에서는 제공하지 않는 퍼지 고객 검색 기능을 서버에서 제공합니다.
연결 및 인증 정보가 제대로 작동하는지 어떻게 확인하나요?
어시스턴트에게 easybill_get_server_info 도구를 호출하도록 요청하면 모드, 제한 사항 및 연결 상태를 확인할 수 있습니다.