Claude koppelen aan Bullhorn met een beveiligde MCP-server
door Maurits, Eigenaar Seerp
Bijgewerkt op
Een recruiter typt: "Welke kandidaten in regio Utrecht hebben ervaring als financial controller, met IFRS en consolidatie?" — en krijgt binnen een paar seconden antwoord uit Bullhorn. Geen zoekscherm, geen filters, geen export naar Excel.
Dat klinkt als een demo. Het interessante zit hem in wat eronder moet zitten voordat je dit bij een recruitmentbureau durft neer te zetten. Wij bouwden het voor Stitch Jobs, en in deze blog laten we zien hoe — inclusief de dingen die misgingen.

Wat is er precies nieuw?
Sinds kort kan Claude verbinding maken met externe systemen via het Model Context Protocol (MCP), een open standaard. Je bouwt een MCP-server die een handvol duidelijk begrensde "tools" aanbiedt — kandidaten zoeken, een profiel ophalen, een vacature erbij zoeken — en Claude roept die aan wanneer het antwoord op een vraag daarin zit.
Het verschil met een chatbot op je website: dit draait bij de recruiter, in de tool waar hij toch al zit, op jullie eigen data, met jullie eigen inlog. Er wordt niets van tevoren geïndexeerd of gekopieerd naar een externe AI-omgeving.
Onder water is het gewoon de Bullhorn REST API, met dezelfde OAuth 2.0-autorisatie die we ook gebruiken voor vacaturewebsites op Bullhorn. Wat erbij komt, is de laag eromheen.
Wat een recruiter er concreet mee doet
- Gericht zoeken op functie-ervaring, vaardigheden, regio en beschikbaarheid, in gewone taal in plaats van in zoekfilters.
- Een profiel voorbereiden voor een intake: werkervaring, vaardigheden, locatie en recente contactmomenten in één samenvatting.
- Profiel en vacature naast elkaar leggen: welke feiten sluiten aan, en — minstens zo nuttig — welke informatie ontbreekt in het dossier.
- Gespreksonderwerpen en opvolging voorbereiden op basis van de vacature, het profiel en de laatste interactie.
- Websitecontent meenemen: actuele online vacatures en bedrijfsinformatie in hetzelfde antwoord.
De recruiter beoordeelt en beslist. De assistent zoekt op, vat samen en benoemt wat er niet is.
Waarom "even een AI'tje eraan knopen" niet volstaat
Hier zit het echte werk, en dit is waar je bij een ATS met kandidaatgegevens niet omheen kunt.
- MCP-server
- Bullhorn REST API
- Microsoft Entra ID
- OAuth 2.0 + PKCE
- Alleen-lezen transportlaag
- Audittrail
- Rate limiting
Alleen-lezen, en dan echt alleen-lezen
De Bullhorn API-user van de meeste bureaus heeft lees- én schrijfrechten. "We bouwen gewoon geen schrijffuncties" is dan geen garantie maar een voornemen — één bug of één onnadenkende uitbreiding verderop is het weg.
Wij dwingen het af in de transportlaag: elk verzoek dat geen GET is wordt geweigerd vóórdat er een netwerkaanroep plaatsvindt. De schrijffuncties zitten niet in dezelfde codebase, dus ze zijn niet eens te importeren. En er staat een test op die faalt zodra iemand die grens omzeilt.
Inloggen met je eigen zakelijke account
De koppeling zit achter Microsoft Entra ID. Recruiters loggen in met hun bestaande werkaccount, en toegang wordt geregeld met app-rollen. Iemand uit dienst? Toewijzing intrekken in Entra en de toegang is direct weg — geen aparte gebruikerslijst die iemand vergeet bij te werken.
Er is geen enkel eindpunt zonder authenticatie. Ook geen statuspagina die per ongeluk configuratie prijsgeeft.
Een audittrail die ergens over gaat
Omdat Bullhorn één gedeelde API-user ziet, staat in het Bullhorn-log bij elke raadpleging dezelfde naam. Onze eigen audittrail is dus de énige plek waar staat wie wat opvroeg.
Daarom is die trail geen bijproduct: bij tools die persoonsgegevens teruggeven worden de resultaten achtergehouden als de auditregel niet wegschrijft. Een niet-vastgelegde raadpleging is geen ontbrekende logregel — het is een raadpleging waar niemand verantwoording over aflegt.
Geen ranking, geen score
Dit is een bewuste keuze met juridische lading. Onder de EU AI Act valt het beoordelen en selecteren van kandidaten onder hoog risico (Annex III). Die verplichtingen zijn met de Digital Omnibus verschoven naar 2 december 2027, maar de transparantieverplichtingen uit artikel 50 gelden sinds 2 augustus 2026 gewoon.
Een assistent die feiten opzoekt en samenvat is iets heel anders dan een assistent die kandidaten rangschikt. Wij houden die grens niet met een instructie in een prompt, maar in het ontwerp: zoekresultaten komen terug gesorteerd op record-id, nooit op relevantie. Een op relevantie gesorteerde lijst ís een shortlist, hoe je hem ook noemt.
De vergelijkingsfunctie tussen profiel en vacature levert dan ook geen cijfer. Hij benoemt welke feiten overeenkomen, welke niet genoemd worden, en welke velden in het dossier leeg zijn.
Grenzen aan het volume
Die Bullhorn API-user wordt vaak gedeeld met nachtelijke synchronisaties en de vacaturewebsite. Eén uitgelopen gesprek kan dus de API-ruimte opsouperen waar andere processen op rekenen. Er zit daarom een limiet per gebruiker op, geteld uit de audittrail zodat hij ook klopt als de dienst over meerdere servers draait.
Wat er onderweg misging
Eerlijk is eerlijk: de koppeling tussen Claude en Entra ID werkte niet uit de doos, en de foutmeldingen hielpen niet.
Entra ondersteunt geen Dynamic Client Registration, en ook geen Client ID Metadata Documents. Dat is een bewuste keuze van Microsoft, geen omissie. MCP-clients verwachten juist dat een van die twee er is. Oplossing: de client vooraf registreren en de client-id en secret handmatig meegeven.
Entra publiceert onvolledige metadata. Beide standaardpaden waar een MCP-client naar zoekt geven een 404, en in het document dat er wél is ontbreekt de vermelding dat PKCE wordt ondersteund — terwijl het gewoon werkt. Een client die die metadata leest om te bepalen of de flow mogelijk is, concludeert dus dat het niet kan. We publiceren dat document nu zelf, met Entra's echte endpoints erin en de ontbrekende verklaringen toegevoegd.
En de fout die het meeste tijd kostte: AADSTS9010010 — the resource parameter provided in the request doesn't match with the requested scopes. De MCP-standaard schrijft voor dat de client de eigen URL van de MCP-server meestuurt als resource-identifier. Entra vergelijkt die met de resource van de gevraagde scope. Bij de standaardwaarde api://<client-id> komen die twee nooit overeen.
Top tip
Krijg je AADSTS9010010 bij het koppelen van een MCP-server aan Entra ID? Zet
de Application ID URI van je app-registratie gelijk aan de URL van je
MCP-server. De oplossing is even simpel als onvindbaar.
Dat soort dingen kost een dag als je weet waar je moet kijken, en een week als je dat niet weet.
Waar je vooraf over moet beslissen
Twee randvoorwaarden die niets met techniek te maken hebben, en die we liever vooraf bespreken dan achteraf:
De licentie bepaalt of je dit met echte kandidaatgegevens mág. De persoonlijke Claude-abonnementen vallen onder consumentenvoorwaarden: geen verwerkersovereenkomst, geen centrale bewaartermijn, geen beheerde intrekking. Voor een technische proef prima. Voor een pilot met echte dossiers heb je een zakelijk abonnement nodig, met de bijbehorende verwerkersovereenkomst.
Een pilot moet "nee" kunnen zeggen. Leg vooraf twintig echte recruitervragen vast, klok hoe lang ze nu duren, en spreek af bij welke tijdwinst en welke foutmarge je doorgaat of stopt. Zonder die twee getallen is een pilot geen test maar een uitrol met extra stappen.
Werkt dit ook op een ander ATS?
Ja. De opzet is bewust in lagen gebouwd: de beveiliging, de rollen, de audittrail en de tools staan los van de koppeling met het bronsysteem. Bullhorn is bij ons de eerste connector, maar hetzelfde patroon werkt op Recruitee, OTYS, Carerix of een eigen database. Een tweede bron toevoegen is een connector schrijven, geen herbouw.
Interesse?
Werk je met Bullhorn of een ander ATS en wil je weten wat dit voor jouw recruiters betekent? We beginnen graag met een korte sessie waarin we vaststellen welke vijf vragen jullie recruiters het vaakst stellen, wat daarvoor uit het systeem moet komen, en of het bij jullie inrichting past.
Bronnen
- Model Context Protocol — de open standaard waarmee Claude verbinding maakt met externe systemen.
- Microsoft Entra ID: OAuth 2.0 authorization code flow — de flow waar de
AADSTS9010010-fout uit voortkomt. - Bullhorn REST API-documentatie — de entiteiten waarop de tools zijn gebouwd.
- EU AI Act (Verordening 2024/1689) — de tekst achter Annex III en artikel 50.