Caowijs
Click on "Deploy 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., "@Caowijshoeveel transitievergoeding krijg ik na twee jaar uitzendwerk?"
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.

Een taalmodel weet veel, maar niet wat er dit jaar in een cao staat, en het zegt er niet bij waar het iets vandaan heeft. Deze connector geeft Claude een kennisbank over de Cao voor Uitzendkrachten 2026-2028 en de regels eromheen. Elk antwoord verwijst naar de bron: de wet, de cao-tekst of de instantie die het bedrag vaststelt.
Het is een MCP-server: een klein programma op je eigen computer waarmee Claude zelf een bron kan raadplegen.
Starten
Je hebt Node 22.18 of hoger nodig.
git clone https://github.com/t1mvdploeg/caowijs.git
cd caowijs && npm install
claude mcp add caowijs -- node "$PWD/src/start.ts"Stel daarna in Claude Code een vraag over de cao. In de Claude-app voeg je dezelfde server toe in het bestand met MCP-servers, met het volledige pad naar src/start.ts.
Related MCP server: Dutch-law-mcp
Wat Claude ermee kan
Tool | Wat het doet |
| Geeft de lijst met onderwerpen, met per pagina de periode en de datum van bijwerken |
| Zoekt op een vraag en geeft de best passende stukken tekst, elk met bron |
| Geeft één hele pagina |
Elk stuk tekst heeft een etiket: geldt nu, historie of open vraag. Zo presenteert Claude geen achterhaalde regel als geldend, en zegt het erbij wanneer de bronnen iets niet beantwoorden of elkaar tegenspreken.
Drie echte vragen met het volledige antwoord van Claude staan in docs/proefvragen.md.
Hoe het werkt
flowchart LR
A[Bronnen<br>wet, cao, StiPP,<br>Belastingdienst, NAU] -->|samenvatten<br>en nalopen| B[kennis/<br>18 pagina's]
B -->|opdelen in stukken<br>met etiket| C[Zoekindex<br>BM25]
D[Claude] -->|vraag| E[MCP-server]
E --> C
C -->|stukken met bron| E
E -->|antwoord met link| DDe kennis staat in
kennis/: 18 pagina's in gewone markdown, waarin elke feitelijke bewering een link naar de bron heeft.De server leest die pagina's bij het starten en deelt ze op in stukken met een etiket.
Zoeken gaat op trefwoorden met BM25, de gangbare formule waarbij een zeldzaam woord zwaarder telt. Een zoekwoord vindt ook samenstellingen: "vergoeding" vindt "transitievergoeding". De keerzijde is een enkele valse treffer bij korte woorden: "tijd" vindt ook "altijd".
De server leest alleen. Hij heeft geen sleutels nodig en maakt geen verbinding met internet.
Er zit bewust geen vectordatabase in. Voor ongeveer 40.000 woorden zijn trefwoorden genoeg: ze kosten niets, geven elke keer dezelfde uitkomst en zijn te testen. Een synoniem dat nergens in de tekst staat vindt hij niet; Claude probeert dan een tweede zoekterm.
Gemeten kwaliteit
In evals/vragen.json staan 54 vragen in gewone taal, elk met de pagina waar het antwoord hoort te staan. Ze zijn geschreven voordat de zoekfunctie bestond.
Meting | Score |
Juiste pagina in de bovenste drie resultaten | 49 van 54 (91%) |
Juiste pagina op één | 46 van 54 (85%) |
De test faalt onder de 90% in de bovenste drie, dus de marge is één vraag. De zoekfunctie is bijgesteld op dezelfde 54 vragen (de eerste meting gaf 48 van 54), waardoor de score aan de gunstige kant ligt. npm run meet herhaalt de meting en toont welke vragen mis gaan.
Wat het niet doet
Het geeft geen juridisch advies. Het zijn samenvattingen, met de stand van 4 oktober 2026.
Het haalt geen nieuwe informatie van internet. Wat na die datum is veranderd, staat er niet in.
Het draait alleen lokaal.
Ontwikkelen
npm test # alle tests, ook de meting en de controle op de openbare pagina's
npm run typecheck
npm run meet # de zoekscore op de testvragenHet ontwerp en het plan staan in docs/.
Bronnen en licentie
De code valt onder de MIT-licentie. De kennispagina's zijn samenvattingen in eigen woorden met een link naar de bron; de bronnen zelf blijven van hun rechthebbenden.
Available Tools
3 toolslees_onderwerpLees een pagina van de cao-kennisbankARead-only
Geeft één hele pagina van de kennisbank, met de opbouw Kern, Details, Historie, Open vragen en Bronnen. Gebruik dit als je de samenhang nodig hebt of als een zoekresultaat te weinig context geeft.
| Name | Required | Description | Default |
|---|---|---|---|
| pagina | Yes | Naam van de pagina, zoals de tool onderwerpen die geeft. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the description doesn't need to restate safety. It adds real value by disclosing the return content shape (Kern, Details, Historie, Open vragen, Bronnen), which no output schema exists to convey. It says nothing about size limits or whether the page label must come from 'onderwerpen', but for a safe read the coverage is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the first describes output, the second gives usage conditions. No filler, and the purpose leads.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully enumerates the page sections, which is exactly the missing return-value information. Combined with the explicit usage trigger, an agent has enough to call it correctly; only the linkage to the 'onderwerpen' label source is left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and there is a single required parameter, so the schema carries the semantic load. The phrase 'één hele pagina' signals that one page is returned per call, but adds no format or provenance detail beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Geeft één hele pagina van de kennisbank') and enumerates the page's internal structure, which tells the agent exactly what it retrieves. It implicitly contrasts with the zoek sibling by mentioning search results, but does not name or distinguish the onderwerpen sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear positive selection criteria: use it when you need the coherence/context, or when a search result supplies too little context. This effectively routes the agent away from 'zoek', though the 'onderwerpen' alternative is never mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
onderwerpenOnderwerpen van de cao-kennisbankARead-only
Geeft de lijst met onderwerpen in de kennisbank over de Cao voor Uitzendkrachten: per pagina de naam, wat ze dekt, voor welke periode ze geldt en wanneer ze is bijgewerkt. Gebruik dit om te zien wat de kennisbank bevat, of als zoeken niets oplevert.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds value beyond that by disclosing what each entry returns (name, coverage, applicable period, last-updated timestamp), which is meaningful given there is no output schema, but it says nothing about result size or how listing interacts with the 'per pagina' framing given there are no pagination parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense but front-loaded sentence: the action leads, the returned fields follow, and the usage condition closes it. No filler or redundant restatement of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only listing with no output schema, the description covers what the tool does, what each entry contains, and when to reach for it. The only soft spot is the slightly ambiguous 'per pagina' phrasing (implies pagination that the empty schema does not expose), which an agent may briefly puzzle over.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so per the rubric the baseline is 4. Nothing in the description needs to compensate for undocumented inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Geeft de lijst met onderwerpen in de kennisbank') scoped to the Cao voor Uitzendkrachten, and contrasts with searching by noting it is the fallback 'als zoeken niets oplevert'. It is clearly distinct from lees_onderwerp (single topic) and zoek (search), though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides two explicit trigger conditions: browsing what the knowledge base contains, or recovering when a search returns nothing. That effectively communicates the alternative to zoek, but gives no negative guidance (e.g. when lees_onderwerp is the better call once you already know the topic name).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zoekZoek in de cao-kennisbankARead-only
Zoekt op trefwoorden in de kennisbank over de Cao voor Uitzendkrachten en geeft de best passende stukken tekst terug, elk met een etiket (geldt nu, historie of open vraag), de pagina en de bron als link. Stel de vraag in gewone Nederlandse woorden, bijvoorbeeld "wachtdagen bij ziekte" of "transitievergoeding berekenen".
| Name | Required | Description | Default |
|---|---|---|---|
| vraag | Yes | De vraag of de zoekwoorden, in het Nederlands. | |
| aantal | No | Aantal resultaten, standaard 5. | |
| onderwerp | No | Naam van één pagina om binnen te zoeken, zoals de tool onderwerpen die geeft. Laat weg om overal te zoeken. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds valuable behavioral detail beyond that: results are labeled as 'geldt nu', 'historie', or 'open vraag' and include page and source link, telling the agent how to interpret result validity. No rate limits or auth requirements are mentioned, but those are not crucial here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences: the first front-loads purpose and return format, the second gives usage and examples. No filler, and the most important information (what is searched and what comes back) leads.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must explain returns, and it does: matching text passages with labels, page, and source link. It does not elaborate on the meaning of the labels or result ranking, and the default result count is left to the schema. Adequate for a 3-parameter read-only search tool, with minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds meaning for the main parameter by instructing to phrase the vraag in ordinary Dutch words and giving concrete examples. It also adds guidance for onderwerp ('Laat weg om overal te zoeken'), which goes beyond the schema's description of that field.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: searches by keyword in the knowledge base about the Cao voor Uitzendkrachten and returns best-matching text passages. The return shape (text pieces with labels, page, source link) is specified, and it implicitly contrasts with siblings lees_onderwerp and onderwerpen by referencing the latter for page scoping. An agent can distinguish this keyword-search tool from the topic-listing and topic-reading siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides useful usage context: ask in plain Dutch, with examples like "wachtdagen bij ziekte", and the onderwerp parameter can restrict to one page or be omitted to search everywhere. However, it never explicitly says when to use this tool versus lees_onderwerp or onderwerpen, nor when not to use it. Usage is implied rather than routed.
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.
3 tool updates
v0.1.0- First observed
lees_onderwerp - First observed
onderwerpen - First observed
zoek
TDQS
Scored across 3 tools
The three tools have clearly distinct roles: one lists all topics, one searches with snippets, and one returns a full page. The descriptions explicitly explain when to use search versus reading a full topic, so an agent can select correctly.
The names are all Dutch and lowercase, but they mix morphological patterns: 'lees_onderwerp' is verb+noun, 'onderwerpen' is a bare plural noun, and 'zoek' is a bare verb. The set is readable but not consistently patterned.
Three tools are well-scoped for a focused knowledge-base retrieval server. Each tool has a distinct retrieval purpose, and there is no excessive surface area.
For a read-only knowledge base, the surface covers discovery (onderwerpen), targeted lookup (zoek), and full-context retrieval (lees_onderwerp). No obvious lifecycle operations are missing for this purpose.
Maintenance
Related MCP Connectors
Dutch legal AI for law firms: answers from Dutch case law, legislation and EU law, with citations.
Verified answers for AI agents: only from approved documents, with sources, or a refusal.
Swiss federal law (Fedlex) and political data (LINDAS) for agents, every answer with sources
Sourced answers on FR/EU rules + French company search (SIREN, NAF) for agents, quoted and budgeted
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP-based AI agent that retrieves and processes documents to answer queries using a RAG pipeline with LangChain and Claude models. It enables document indexing, context-aware retrieval, and multi-tool orchestration for research and knowledgebase applications.1-
- AlicenseAqualityFmaintenanceEnables querying over 3,200 Dutch statutes (AVG, Wetboek van Strafrecht, Burgerlijk Wetboek, etc.) with verbatim, citation-grounded text from official sources, directly from MCP-compatible AI assistants.1842 npm14Apache 2.0
- AlicenseAqualityCmaintenanceEnables searching medical literature, clinical trials, drug information, guidelines, and medical fee schedules directly from Claude, returning only original sources and text without medical judgment.9MIT
- FlicenseNot gradedqualityBmaintenanceEnables Claude to retrieve and cite clauses from Korean national R&D manuals using RAG, grounding answers with accurate provision references.-