konto-mcp
v2.1.2
Published
MCP server for the Konto accounting and invoicing API — exposes 39 tools across customers, items, invoices, costs, tasks, and sell-products. OAuth2 with scoped Bearer tokens.
Readme
Konto MCP Server
An MCP (Model Context Protocol) server that exposes the Konto accounting and invoicing API to Claude, ChatGPT, Cursor, and any MCP-compatible client. 39 tools across customers, items, invoices, costs, tasks, sell-products, and account.
Two ways to connect
- Hosted connector (recommended for most). Add
https://mcp.konto.is/mcpin Claude / ChatGPT / Cursor / any MCP client, sign in with Konto, done — no install, no api-keys to paste. → docs/connect.md for the per-tool steps. - Local install. Run the server on your own machine with tokens stored on-device — best for power users, scripting, and offline development. That's the rest of this README.
Local install — get started in 3 minutes
You'll do this once per machine. After that, every Claude Desktop session can read and write your Konto data via natural-language prompts.
1. Find your Konto api_key
Sign in to konto.is in your browser. Open Settings → Webservice and copy the api_key. Keep the browser tab open — you'll come back to it in step 3.
Requires a plan that includes API access (Sheets, Sprouts, or above with the webservice add-on). Free-tier accounts get a clear "upgrade your plan" message from
setuprather than an unusable token.
2. Run the one-time OAuth setup
Open a terminal (Terminal on macOS / Linux, PowerShell on Windows) and run:
npx -y konto-mcp setup --username your_username --api-key-stdinThe CLI prompts:
Konto API key: ███████████████ (no echo)Paste the api_key from step 1 and press Enter. The key won't appear on screen and is not saved to your shell history.
Why the api_key here if this is OAuth? It's used once — to register your OAuth client with Konto — then discarded. It never lands on disk and is never sent again. Every tool call afterward uses short-lived OAuth Bearer tokens.
3. Click Allow in the browser
Your default browser opens to Konto's agent-consent page. Because you're already signed in (step 1), it's just a consent dialog:
konto-mcp would like to access your account. Requested scopes:
cost,create_invoice,task, … [ Allow ] [ Deny ]
Click Allow. The browser shows "Authorization complete — you can close this tab." Close it.
Back in your terminal:
✓ Authorized.
Granted scopes: cost, create_invoice, task
Access token expires in 86400s.
Config saved to: ~/.config/konto-mcp/config.jsonThe api_key is thrown away at this point — only OAuth tokens are persisted (user-only file permissions). Tokens auto-refresh on every API call.
4. Tell Claude Desktop about konto-mcp
In Claude Desktop: Settings → Developer → Edit Config. Paste:
{
"mcpServers": {
"konto": {
"command": "npx",
"args": ["-y", "konto-mcp"]
}
}
}No secrets in this file — the MCP reads its own tokens from the config saved in step 3.
5. Restart Claude Desktop and try it
Quit and reopen Claude Desktop. The konto_* tools appear under the 🔌 connector menu.
Ask Claude:
"List my last five Konto costs from May."
Done.
Example prompts
- "List my open invoices from the last 30 days."
- "Create an invoice for customer Acme Corp for 3 hours of consulting at 15,000 ISK/hr."
- "Add this receipt as a cost." (attach an image — Konto's Cost AI extracts the supplier, amount, VAT, date)
- "How many costs from supplier X this quarter?"
- "Show me all open tasks and start the timer on the first one."
- "Create a new customer: Acme Corp, email [email protected], Reykjavik."
Tools
Full per-tool reference — parameters, scopes, examples, and the write-side rules Konto enforces: docs/tools.md.
| Group | Tools | |-------|-------| | Customer | list, count, get, create, update | | Item | list, count, get, create, update | | Invoice | list, get, create, create recurring, update | | Cost | list, count, get, create, create adv, update, delete | | Task | list, count, get, create, start, end, log, edit log, deactivate, delete log | | Sell Product | list, count, list attendees | | Account | status (health check + identity), list agents, revoke agent |
File uploads on konto_create_cost and konto_create_cost_adv are passed as file_base64 + file_name. Allowed types: jpg, jpeg, png, gif, pdf. Max 5 MB. (The MCP host — Claude Desktop, etc. — already exposes attached files in base64 form.)
Alternative: env-var API key (legacy)
If you'd rather not run the OAuth setup and prefer to drop your api_key into Claude Desktop's config directly, this older path still works:
{
"mcpServers": {
"konto": {
"command": "npx",
"args": ["-y", "konto-mcp"],
"env": {
"KONTO_USERNAME": "your_username",
"KONTO_API_KEY": "your_api_key"
}
}
}
}Trade-offs vs. OAuth:
- + Single config file, no terminal step.
- − Your api_key lives in plain text in
claude_desktop_config.json. Anyone with read access to that file has full account access. - − No scope narrowing — the api_key has full account permissions.
- − No clean revoke. To rotate, regenerate the api_key in Konto and update the config.
For most users, the OAuth flow above is the better choice.
CLI reference
konto-mcp Start the MCP server (default)
konto-mcp setup [...] Run the OAuth setup flow
konto-mcp status Show what's configured (no secrets)
konto-mcp logout Clear the saved OAuth config
konto-mcp --version, -v Print version
konto-mcp --help, -h Show helpkonto-mcp setup flags
Headless (recommended):
--username <name> Konto username
--api-key-stdin Read api_key from stdin (no echo, no history)
--api-key-env <VAR> Read api_key from an environment variable
--api-key <key> api_key as a CLI argument (DISCOURAGED — visible
to `ps` / tasklist and shell history)
Pre-minted client (advanced):
--client-id <id> Existing agent client_id
--client-secret <key> Existing agent client_secret
Common options:
--base-url <url> API base (default https://konto.is/api/v1)
--scopes <list> Comma-separated scopes (default: all 7)
Valid: nav, create_invoice, cost, bookkeeper,
recurring, dashboard_data, task
--name <text> Agent client display name (default: "konto-mcp")
--port <n> Fixed callback port (default 54321)Server-mode flags (legacy env-var path)
--username <name> Konto username (or set KONTO_USERNAME)
--api-key <key> Konto API key (or set KONTO_API_KEY)
--base-url <url> API base URL (default https://konto.is/api/v1)CLI flags take precedence over environment variables.
Configuration files
OAuth tokens are stored under your platform's user-config directory:
| OS | Path |
|---|---|
| Windows | %APPDATA%\konto-mcp\config.json |
| macOS | ~/Library/Application Support/konto-mcp/config.json |
| Linux | ${XDG_CONFIG_HOME:-~/.config}/konto-mcp/config.json |
File mode is 0600 on POSIX. Windows inherits per-user ACLs from %APPDATA%. Tokens never appear in claude_desktop_config.json.
Environment variables
| Variable | Required | Default | Notes |
|---|---|---|---|
| KONTO_USERNAME | only for legacy env-var path | — | Your Konto username |
| KONTO_API_KEY | only for legacy env-var path | — | Generated in Settings → Webservice |
| KONTO_BASE_URL | no | https://konto.is/api/v1 | Use https://dev.konto.is/api/v1 for dev |
| NODE_TLS_REJECT_UNAUTHORIZED | no | — | Set to 0 only when targeting dev.konto.is (self-signed cert). The CLI refuses to run with =0 against production hosts. |
Security notes
- Tokens, not api_keys, on disk. After
setup, your api_key is discarded. Only short-lived access tokens + rotating refresh tokens live on disk, scoped to the permissions the agent client requested. - Scopes. Konto only grants the scopes your subscription includes. Free-tier users with no webservice add-on get a clear "upgrade your plan" message from
setupinstead of an unusable token. - File uploads.
konto_create_cost/konto_create_cost_advaccept files only as base64 + filename (no arbitrary file-path reads). Magic-byte verification ensures the content matches the declared extension. - TLS guard. The CLI refuses to start with
NODE_TLS_REJECT_UNAUTHORIZED=0unless the base URL points atdev.konto.is,localhost, or127.0.0.1. - Revoking access. To revoke konto-mcp's access to your account at any time, visit
https://konto.is/strax/agent/manageand remove the registered client. Runnpx konto-mcp logoutlocally to drop the cached tokens.
Troubleshooting
npx fails with "Permission denied" when the tarball path contains spaces (e.g. C:\Users\Jón Á\OneDrive\...). npx -y <path>.tgz mis-parses paths with spaces. Either:
- use the
file:prefix:npx -y "file:C:/path with spaces/konto-mcp-2.0.3.tgz", or - move the tarball to a space-free path (e.g.
C:\temp\konto-mcp-2.0.3.tgz).
This only affects tarball installs — npx -y konto-mcp from the npm registry is unaffected.
A tool answers "needs the nav scope" (items, invoice lists). Konto gates read access behind the nav subscription feature. If your plan doesn't include it, those tools correctly refuse — upgrade the plan and re-run npx konto-mcp setup to pick up the scope.
Local development
git clone https://github.com/Konto-ehf/konto-mcp.git
cd konto-mcp
npm install
npm run build
npm linkThen point Claude Desktop at the local konto-mcp:
{
"mcpServers": {
"konto": {
"command": "konto-mcp"
}
}
}Edit src/tools/*.ts → npm run build → restart Claude Desktop.
Project structure
konto-mcp/
├── bin/
│ └── konto-mcp.js # CLI shim (npx entry point)
├── src/
│ ├── index.ts # MCP server entry (stdio transport)
│ ├── konto-client.ts # HTTP client (Bearer or basic auth)
│ ├── oauth/
│ │ ├── setup.ts # `konto-mcp setup` orchestration
│ │ ├── flow.ts # /authorize, /token, /register
│ │ ├── store.ts # config read/write (mode 0600)
│ │ ├── browser.ts # cross-platform browser launcher
│ │ └── paths.ts # platform-conventional config dir
│ ├── tools/
│ │ ├── customers.ts
│ │ ├── items.ts
│ │ ├── invoices.ts
│ │ ├── costs.ts
│ │ ├── tasks.ts
│ │ └── sell-products.ts
│ └── util/
│ └── sanitize-error.ts # strips PHP stack frames from API errors
├── package.json
└── tsconfig.jsonLicense
MIT
