Ga naar inhoud

Koppel een externe capability via MCP

Aan het eind van deze tutorial zoekt een model in Core tickets op via de MCP-server van het ticketsysteem van Noordwind. Je hebt de server geregistreerd, gekozen welke van zijn tools je toestaat, en ze aan een verzoek en aan een agent gegeven.

Bouwstenen MCP: Core gebruikt een MCP-server. Tools: toolsets en toegestane bestemmingen. Sleutels, capabilities en policy
Je hebt nodig een sleutel met de capability tooling (en agents voor stap 6); het adres van een MCP-server en een token ervoor; een beheerder van je organisatie, of een sleutel met management, voor stap 1; voor de trace bij de controle moet de opslag van traces aanstaan voor je organisatie (Een trace lezen)
Bouwt voort op niets. Stap 6 gebruikt de agent uit Bouw je eerste agent als je die hebt

MCP (Model Context Protocol) is een standaard waarmee een server tools aanbiedt. Kies deze weg als het systeem dat je wilt aansluiten al een MCP-server heeft: je krijgt dan al zijn tools met hun omschrijvingen en schema's in één registratie. Heeft het systeem alleen een HTTP-API, dan is een API-koppeling korter.

De voorbeelden gebruiken https://mcp.tickets.example.com/ met de tools search_tickets, get_ticket en close_ticket. Vervang het adres door dat van je eigen server.

1. Sta de host toe

Core leest de toollijst van de server en roept later zijn tools aan. Beide zijn uitgaande aanroepen, en een organisatie bereikt geen host tot ze die toestaat. In de console: open Instellingen, het tabblad Toegang & policy, kies Host toevoegen op de kaart Toegestane hosts, vul mcp.tickets.example.com in en kies Host toestaan.

Met een sleutel die management heeft:

curl -s -X POST "$CORE_URL/organisation/allowed-hosts" \
    -H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
    -d '{"host": "mcp.tickets.example.com"}'

Je doet dit eerst, zodat de eerste leesbeurt na het registreren meteen slaagt.

2. Registreer de server

curl -s -X POST "$CORE_URL/mcp_servers" \
    -H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
    -d '{"name": "tickets",
         "url": "https://mcp.tickets.example.com/",
         "auth": {"type": "bearer", "secret": "Bearer <het token van de server>"}}'

Het antwoord is 201 (ingekort):

{
  "id": "mcp_6Tq1...",
  "name": "tickets",
  "allowed_tools": null,
  "last_synced_at": null,
  "last_sync_error": null,
  "tool_count": 0,
  "egress": [{ "host": "mcp.tickets.example.com", "allowed": true, "blocked": false }]
}
export SERVER_ID=mcp_6Tq1...

De naam tickets komt in elke toolnaam terug (mcp__tickets__<tool>) en wijzigt daarna niet meer. Het token bewaar je bij de registratie: Core stuurt het mee bij het lezen van de toollijst en bij elke aanroep, en geeft het nooit terug.

3. Wacht op de eerste leesbeurt

Core leest de toollijst kort na het registreren op de achtergrond.

curl -s "$CORE_URL/mcp_servers/$SERVER_ID" -H "Authorization: Bearer $CORE_KEY"

Herhaal dit tot last_synced_at een tijdstip bevat. Is last_sync_error dan null en tool_count groter dan nul, dan is de server gelezen. Een server zonder geslaagde leesbeurt biedt een beurt geen tools aan. Een nieuwe leesbeurt vraag je met POST /mcp_servers/$SERVER_ID/sync; dat antwoordt 202.

4. Kies welke tools je toestaat

curl -s "$CORE_URL/mcp_servers/$SERVER_ID/tools" -H "Authorization: Bearer $CORE_KEY"
{
  "items": [
    { "name": "search_tickets", "description": "Zoekt tickets op trefwoord of klant.", "offered": true },
    { "name": "get_ticket", "description": "Leest één ticket.", "offered": true },
    { "name": "close_ticket", "description": "Sluit een ticket.", "offered": true }
  ]
}

Zolang allowed_tools null is, biedt de registratie elke tool van de server aan, ook een tool die de server later toevoegt. Voor een assistent die alleen hoeft te lezen, is dat te ruim:

curl -s -X PATCH "$CORE_URL/mcp_servers/$SERVER_ID" \
    -H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
    -d '{"allowed_tools": ["search_tickets", "get_ticket"]}'

close_ticket staat daarna op offered: false en bereikt geen enkele beurt. Je beperkt bij de registratie en niet per verzoek, omdat de server van iemand anders is: wat hij morgen aanbiedt, bepaal jij niet.

In de console doe je stap 2 tot en met 4 onder MCP-servers.

5. Bied de tools aan op een verzoek

Elke geregistreerde server is ook een toolset van haar eigen tools. Je noemt de set, of één tool:

curl -s -X POST "$CORE_URL/responses" \
    -H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
    -d '{"model": "<een model-id>",
         "tools": [{"type": "toolset", "name": "mcp__tickets"}],
         "input": "Welke tickets staan er open over beschadigde bestellingen?"}'

Eén tool noem je met {"type": "tool", "name": "mcp__tickets__search_tickets"}. De toolset beweegt mee met wat de registratie toestaat; een losse toolnaam ligt vast. Gebruik de set als je de hele server bedoelt en de losse naam als een beurt precies één ding mag.

6. Geef de tools aan een agent

curl -s -X POST "$CORE_URL/agents/$AGENT_ID/versions" \
    -H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
    -d '{"model": "<een model-id>",
         "instructions": "Je bent de supportassistent van Noordwind. Antwoord kort en in het Nederlands. Zoek bestaande tickets op voordat je iets over de status van een melding zegt.",
         "temperature": 0.2,
         "tools": [{"type": "toolset", "name": "mcp__tickets"}]}'

Een versie is de hele definitie. Heeft je agent al andere tools uit eerdere tutorials, neem die dan op in dezelfde lijst tools.

Controleer of het werkt

Het antwoord op stap 5 (ingekort) bevat de aanroep van de MCP-tool:

{
  "status": "completed",
  "output": [
    { "type": "mcp_call", "name": "mcp__tickets__search_tickets", "server_label": "mcp__tickets",
      "arguments": "{\"query\": \"beschadigd\"}", "status": "completed", "output": "..." },
    { "type": "message", "role": "assistant",
      "content": [{ "type": "output_text", "text": "Er staan twee tickets open: ..." }] }
  ]
}

De argumenten en de uitvoer hangen af van je server. GET /tools?source=mcp toont de MCP-tools die je sleutel kan aanbieden; close_ticket hoort daar niet meer bij. De trace van de beurt (GET /responses/{id}/trace) toont de uitvoering onder tool_calls, met source: "mcp".

Als het niet werkt

Je ziet Oorzaak Oplossing
404 op POST /mcp_servers de capability tooling staat uit op je sleutel of in het plafond van je organisatie vraag je beheerder hem aan te zetten (Capabilities)
last_sync_error is gevuld Core kon de server niet lezen, en de zin zegt waarom: de host is niet toegestaan, het adres is onbereikbaar, de server weigerde de inloggegevens met 401 of 403, hij gaf meer dan 1000 tools of meer dan 2 MiB aan tooldefinities op, twee van zijn tools komen op één naam uit, of het adres is een van je eigen toolsets op deze Core controleer egress op GET /mcp_servers/{id}, herstel de oorzaak en stuur POST .../sync
het model krijgt geen tools de server is nog niet gelezen, of allowed_tools sluit ze uit stap 3 en 4
404 op POST /responses de toolnaam of de toolset bestaat niet voor je sleutel lees de namen met GET /tools?source=mcp
400 met tools of tools.N.name in error.param twee tools op het verzoek hebben voor het model dezelfde naam; tools.N.name is een eigen tool die precies zo heet als een tool die Core in hetzelfde verzoek uitvoert bied elke tool één keer aan, of geef je eigen tool een andere naam
"Tool endpoint refused the credential." in het antwoord de server beantwoordde de aanroep met 401 of 403 controleer de inloggegevens die bij de server zijn opgeslagen
"Denied by policy." in het antwoord de host van de server is niet toegestaan, of een regel over Bestemmingen van je sleutel sluit hem uit controleer egress op GET /mcp_servers/{id} en herhaal stap 1
de host staat op je lijst en de aanroep wordt toch geweigerd een organisatie boven de jouwe staat de host niet toe (egress geeft dan allowed: false), of ze beperkt regio's waarin de host niet draait vraag de beheerder van de organisatie erboven de host toe te staan (Policy)
het model krijgt een tool niet die wel offered: true is de policy van je sleutel staat de tool niet toe; Core biedt hem dan niet aan lees de regels over Tools met GET /key

Verder

Volgende tutorial: Bouw een agent die knowledge én tools combineert.