MCP server
MCP (Model Context Protocol) is how AI clients are given tools. schakl. serves one at /mcp: every
endpoint of the API is a tool there. You connect Claude Desktop, Claude Code or any other MCP client
to your own installation and ask your question in plain language, without exporting anything first.
What the AI may see and do is decided by the scopes on the key you hand it.
Where to find it
Section titled “Where to find it”The server runs at https://<your-host>/mcp, on your organisation’s own address. There is no screen
for it: you configure it on the client side, using a key from Instellingen → Mijn account
(Settings → My account, the API-sleutels block) or from Instellingen → Service-accounts
(Settings → Service accounts).
Connecting
Section titled “Connecting”-
Mint a key as described under REST API. Under Scopes, tick only what the AI may do — for asking questions that is usually read permissions only.
-
Copy the key immediately. It is shown only once.
-
Add the server to your client. For Claude Code:
Terminal window claude mcp add --transport http schakl https://<your-host>/mcp \--header "Authorization: Bearer schakl_…" -
Any other client that speaks Streamable HTTP: point it at the same address with the header
Authorization: Bearer schakl_…orX-API-Key: schakl_…. -
Ask the client to list its tools. If nothing appears, check that you used your organisation’s own address — a key only exists on its own organisation’s hostname.
What tools the AI gets
Section titled “What tools the AI gets”The tool list is derived straight from the API itself, so it never lags behind. Every endpoint under
/api/v1 is a tool, named after the operation: list_companies, create_task, time_summary.
Only the modules your organisation has switched on have endpoints, so the tool list automatically follows which modules you use. Turn a module off and its tools disappear.
A few things are deliberately left out:
| Not a tool | Why |
|---|---|
| Signing in and the first-run wizard | session handling, meaningless for a key |
| The instance operator’s administration surface | that belongs to the instance owner, not the organisation |
| Import: inspecting a file and importing it | those need a file, plus the human judgement of mapping columns |
The rest of import and export stays available: reading an entity’s columns and exporting data are both useful to an AI.
Too many tools for a chat client
Section titled “Too many tools for a chat client”The full surface is ~620 tools, and that is the right default for a coding agent, which reads the list once. It is the wrong one for a chat client, which puts every tool in the model’s context on every turn and therefore budgets: ChatGPT allows 5,000 tokens for all tools together, and the full list is around 527,000. No amount of trimming closes that gap — at that count you have about 85 tokens per tool, which does not buy a name. Only fewer tools works.
So the same server answers on narrower URLs, and you paste whichever one fits the client:
| URL | What it offers |
|---|---|
/mcp | Everything. The default, and what a coding agent wants |
/mcp/compact | A curated read-only fourteen, small enough for a chat client’s ceiling |
/mcp/<module> | One module’s own endpoints, for example /mcp/google-ads or /mcp/invoicing |
/mcp/<bundle> | A named job spanning several modules, for example /mcp/infra or /mcp/growth |
A module section is derived from that module’s own routes, so an endpoint added tomorrow is served tomorrow; a bundle names modules, never tools, which keeps it as self-maintaining as the sections it unions. A URL that names nothing is refused and tells you what does exist, rather than quietly falling back to all 620 — that would look like it worked and could not be spotted by reading.
What the AI may and may not do
Section titled “What the AI may and may not do”A tool call travels exactly the same path as an ordinary request from a screen: hostname to organisation, row-level isolation in the database, then that endpoint’s own permission check. There is no second route to the data. A call the key holds no permission for simply comes back as an error on the tool.
Do watch what you tick: the tool surface includes writes, because it is the whole API. If you want the AI to read along only, give the key read permissions only. That is a choice you make when minting the key, not something the server enforces for you.
Permissions
Section titled “Permissions”| Permission | What it opens | Default |
|---|---|---|
apikeys.personal.manage | Manage own API keys | Administrator, Member |
apikeys.service_account.manage | Manage service accounts | Administrator |
After that the key decides everything: each ticked scope is a permission from the same catalogue as Instellingen → Rollen (Settings → Roles). A personal key is additionally re-capped to its owner’s live permissions on every single request.
Good to know
Section titled “Good to know”- API keys are the only way in today. The full OAuth sign-in flow some MCP clients expect is not implemented, so such a client cannot connect yet.
- The transport is Streamable HTTP with self-contained JSON responses. The older SSE transport is not offered.
- 600 calls per minute per key. An AI that searches enthusiastically can run into that.
- Intrekken (Revoke) in the key screen removes access immediately, with nothing to change on the client side.
- The tool list comes entirely from the API description. Hand-written, smarter tools (such as “find this client”) do exist inside the in-app assistant, but are not part of this list.
- To not serve the server at all, set
SCHAKL_MCP_ENABLED=falseon the server. That removes/mcpentirely.