Naar de inhoud
Subsido

De API gebruiken

MCP-server

Een Model Context Protocol-server, zodat een AI-agent maatregelen kan zoeken, een onderneming kan matchen en een match kan uitleggen, met dezelfde sleutel, dezelfde limieten en dezelfde antwoorden als de REST API.

Het endpoint

EigenschapWaarde
URLPOST https://api.subsido.be/mcp
TransportStreamable HTTP, stateless: elke request is één JSON-RPC 2.0-bericht (of een batch), beantwoord met gewone JSON. Geen sessie, geen server-sent events; een GET krijgt 405 method_not_allowed.
AuthenticatieJe API-sleutel als bearer-token: Authorization: Bearer sb_live_....
Protocolversies2025-06-18, 2025-03-26, 2024-11-05. De server beantwoordt initialize met de gevraagde versie als hij die ondersteunt, anders met de nieuwste.
Methodesinitialize, ping, tools/list, tools/call. Een notificatie (een bericht zonder id) wordt bevestigd met 202.
LimietenDezelfde als op de REST-routes: elke POST is één request voor je rate limit en maandquotum, en de matchingtools tellen daarnaast elk één match-evaluatie. De tool voor de change feed vraagt het Developer-plan, net als /v1/changes.

Tools

Elke tool leest alleen en wijzigt niets. Argumenten worden precies zo gevalideerd als de bijbehorende route haar parameters valideert.

ToolArgumentenGeeft terug
search_subsidiesq, region, topic, company_size, instrument_type, status, nace, deadline_before, language, limit (1 tot 25)Compacte records, zoals GET /v1/subsidies: { results, has_more, disclaimer }. Alleen de eerste pagina.
get_subsidyid (id of slug, verplicht), languageHet volledige record, zoals GET /v1/subsidies/{id}.
match_companycompany, project, language, limit (1 tot 25, standaard 10){ matches, matched, missing_information, disclaimer }, zoals POST /v1/match met de standaardopties. Eén match-evaluatie.
explain_eligibilitysubsidy_id (verplicht), company, project, languageEén maatregel geëvalueerd voor de onderneming, ongeacht status of thema’s, ook als een regel hem uitsluit: { match, subsidy, disclaimer }. Eén match-evaluatie.
list_changessince, type, source, region, subsidy, cursor, limit (1 tot 50){ changes, has_more, next_cursor, latest_seq }: de events van GET /v1/changes, met dezelfde filters, dezelfde cursor en elk event in dezelfde vorm. Geef next_cursor terug als cursor om verder te gaan, en later opnieuw om alleen het nieuwe te krijgen. Developer-plan en hoger.
list_sourcesgeen{ sources }, per bron met id, name, rights_mode, licence, freshness, measures, enabled.

Het argument company toont de gebruikelijke eigenschappen (postcode, gewest, grootte, werknemers, omzet, balanstotaal, NACE-codes, rechtsvorm, oprichtingsdatum, de-minimissteun) en aanvaardt elke eigenschap van een matchrequest. Een resultaat komt terug als tekst (opgemaakte JSON) en als structuredContent. Een tool die faalt (een ongeldig argument, een plan dat de sleutel niet heeft, een opgebruikte hoeveelheid) geeft een resultaat met isError: true en de API-fout in structuredContent.error, zodat het model kan lezen wat er misging; alleen een misvormd bericht is een JSON-RPC-fout.

Wat de server het model vertelt

Het antwoord op initialize bevat instructies die eindigen met de onafhankelijkheidszin, in het Engels: “Independent service. Not affiliated with, endorsed by, or operated by any government or public authority. Eligibility and awards are decided by the competent authority.” Elk toolresultaat bevat hem ook. Een model dat een match herhaalt, hoort “waarschijnlijk” of “mogelijk” in aanmerking te zeggen en naar de officiële pagina te linken.

Een client koppelen

Claude Code

claude mcp add --transport http subsido https://api.subsido.be/mcp \  --header "Authorization: Bearer sb_live_..."

Of in de .mcp.json van een project, met de sleutel uit de omgeving zodat hij niet mee gecommit wordt:

.mcp.json
{
  "mcpServers": {
    "subsido": {
      "type": "http",
      "url": "https://api.subsido.be/mcp",
      "headers": {
        "Authorization": "Bearer ${SUBSIDY_API_KEY}"
      }
    }
  }
}

Claude Desktop

Claude Desktop start lokale servers vanuit zijn configuratiebestand, dus een externe server met een sleutel loopt via de brug mcp-remote (die Node.js nodig heeft). In claude_desktop_config.json (Settings, Developer, Edit config):

claude_desktop_config.json
{
  "mcpServers": {
    "subsido": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://api.subsido.be/mcp",
        "--header",
        "Authorization:${AUTH_HEADER}"
      ],
      "env": {
        "AUTH_HEADER": "Bearer sb_live_..."
      }
    }
  }
}

De header gaat via een omgevingsvariabele omdat sommige systemen argumenten splitsen op de spatie in Bearer …. Herstart Claude Desktop na de wijziging.

Andere clients

Elke client die Streamable HTTP spreekt en een header kan meesturen, werkt: geef hem de URL en de header Authorization. Veel clients (Cursor, VS Code, Windsurf) nemen een JSON-blok van deze vorm:

JSON
{
  "mcpServers": {
    "subsido": {
      "url": "https://api.subsido.be/mcp",
      "headers": {
        "Authorization": "Bearer sb_live_..."
      }
    }
  }
}

Een client die alleen lokale servers draait, kan de brug mcp-remote gebruiken zoals hierboven.

Met de hand

Omdat de server stateless is, is curl een volwaardige client. Vraag de tools op en roep er dan een aan:

curl -X POST "https://api.subsido.be/mcp" \  -H "Authorization: Bearer sb_live_..." \  -H "Content-Type: application/json" \  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
curl -X POST "https://api.subsido.be/mcp" \  -H "Authorization: Bearer sb_live_..." \  -H "Content-Type: application/json" \  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": {"name": "match_company", "arguments": {"company": {"postcode": "4000", "employees": 8, "legal_form": "srl"}, "project": {"topics": ["digitalisation"], "budget_eur": 15000}, "language": "fr", "limit": 5}}}'
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\n  \"matches\": [ … ],\n  \"matched\": 9,\n  …\n}"
      }
    ],
    "structuredContent": {
      "matches": [
        "…"
      ],
      "matched": 9,
      "missing_information": [
        "…"
      ],
      "disclaimer": "Independent service. Not affiliated with, endorsed by, or operated by any government or public authority. Eligibility and awards are decided by the competent authority."
    },
    "isError": false
  }
}
  • Fouten van het protocol zelf: -32700 voor een body die geen JSON is (met HTTP 400), -32600 als jsonrpc niet "2.0" is, -32601 voor een onbekende methode.
  • Zonder geldige sleutel antwoordt het endpoint 401, en met een sleutel van een account zonder plan 402 subscription_required, in de gewone foutstructuur van de API, nog voor er JSON-RPC gelezen wordt. Zie authenticatie.