Een waarde van je klant aan een tool meegeven¶
Het concept achter tools staat in Tools.
Soms hoort een waarde niet bij de tool en ook niet bij het model, maar bij het verzoek: het
account-id van je klant in je eigen systeem, de regio die je per klant kiest, of het eigen token van
je klant voor jouw API. Zo'n waarde is een aanroepvariabele. De tool declareert welke
aanroepvariabelen hij leest, jouw applicatie stuurt de waarden mee in tool_variables, en Core vult
ze in bij elke aanroep van die tool. Het model ziet ze nooit en kan ze niet veranderen.
Een tool kent zo drie soorten waarden:
| Soort | Teken in een sjabloon | Wie geeft hem | Wanneer |
|---|---|---|---|
| Argument | {naam} |
het model | bij elke aanroep, in de argumenten |
| Invulwaarde | {$naam} |
de maker van de tool, of de organisatie die hem uit een bundel installeert | bij het registreren of installeren (Waarden die je één keer vastlegt) |
| Aanroepvariabele | {@naam} |
jouw applicatie | bij elk verzoek, in tool_variables |
Je declareert en wijzigt aanroepvariabelen via de API of in de console. De consolepagina's beschrijven dezelfde velden voor een API-koppeling, een MCP-server, een script, een workflow en een alias; een planning bewaart de waarden die ze meestuurt, en de console toont de variabelen die de tools van een agent nodig hebben.
Een aanroepvariabele is iets anders dan de variabelen van een agent of prompt. Die waarden
(agent.variables) komen in de context die het model leest. Stuur een token van je klant daarom
nooit in agent.variables, maar altijd in tool_variables.
Aanroepvariabelen declareren op een API-koppeling¶
Een API-koppeling declareert haar aanroepvariabelen in call_variables: een JSON Schema-object met
één eigenschap per variabele. Elke eigenschap is een string, number, integer of boolean, met
een optionele description, enum en default. required noemt de variabelen waarvoor een
aanroep een waarde nodig heeft. Een naam bestaat uit kleine letters, cijfers en _, en begint met een letter of
cijfer.
Dit voorbeeld leest de bestellingen van één klant uit jouw API, met het eigen token van die klant:
curl -s -X POST "$CORE_URL/api_connectors" \
-H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
-d '{"name": "orders",
"http_url": "https://api.jouw-app.example/v1/accounts/{@account_id}/orders",
"description": "De openstaande bestellingen van deze klant.",
"parameters": {"type": "object", "properties": {"status": {"type": "string"}}},
"request": {"method": "GET",
"query": {"status": "{status}"},
"headers": {"Authorization": "Bearer {@customer_token}"}},
"call_variables": {
"type": "object",
"properties": {
"account_id": {"type": "string", "description": "Het account van de klant bij jou"},
"customer_token": {"type": "string", "x-secret": true}},
"required": ["account_id", "customer_token"]},
"auth": {"type": "none"}}'
customer_token is een geheim (x-secret: true, zie Geheime waarden), dus
mag hij alleen in de header staan. auth blijft none, omdat het token per verzoek verschilt; een credential
dat voor iedereen hetzelfde is, hoort in auth (Je legitimeren bij je
endpoint).
Een aanroepvariabele mag op dezelfde plekken staan als een invulwaarde: in het pad en de query van
http_url, en in een querywaarde, headerwaarde of string in de body van request. In de URL wordt
de waarde percent-encoded, in een query- of headerwaarde is hij tekst, en een bodystring die precies
één {@naam} is wordt de waarde zelf, van zijn eigen type. Een optionele variabele zonder waarde en
zonder default wordt lege tekst, en null waar hij een hele bodywaarde is. Core vult eerst de
invulwaarden in, dan de aanroepvariabelen, dan de argumenten van het model.
Registratie geeft 422 op call_variables bij:
- een
{@naam}die niet gedeclareerd is, of een declaratie die geen{@naam}gebruikt; - een
{@naam}in het schema, de host, de poort of het fragment van de URL, of in een sleutel; - een naam die ook een argument of een invulwaarde is;
- een geheime variabele in de URL of een querywaarde.
Een aanroepvariabele kiest dus nooit de host: een host die per verzoek verschilt, zou het credential van je organisatie naar een host van de aanroeper kunnen sturen.
Een PATCH met call_variables vervangt de hele declaratie en maakt een nieuwe
versie van de koppeling.
Aanroepvariabelen declareren op een MCP-server¶
Een MCP-server accepteert aanroepvariabelen alleen in headerwaarden. Core leest de toollijst van een server op de achtergrond, zonder verzoek, dus een URL die een aanroepvariabele nodig heeft zou nooit gelezen kunnen worden.
curl -s -X POST "$CORE_URL/mcp_servers" \
-H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
-d '{"name": "crm", "url": "https://mcp.jouw-app.example/{$workspace}/mcp",
"headers": {"X-Api-Key": "{$api_key}", "Authorization": "Bearer {@customer_token}"},
"install_values": {
"workspace": {"type": "string", "value": "acme"},
"api_key": {"type": "secret", "value": "fake-api-key-for-docs-0001"}},
"call_variables": {
"type": "object",
"properties": {"customer_token": {"type": "string", "x-secret": true}},
"required": ["customer_token"]},
"auth": {"type": "none"}}'
headerszijn de headers die elk verzoek aan de server draagt. Een waarde mag{$naam}invulwaarden en{@naam}aanroepvariabelen bevatten.install_valueswerken zoals bij een API-koppeling. Een gewone invulwaarde mag in het pad en de query van de URL en in een headerwaarde staan; eensecretalleen in een headerwaarde.- Een header met een aanroepvariabele laat Core weg bij het lezen van de toollijst, omdat daar geen verzoek is om een waarde uit te halen. Je server moet zijn toollijst dus ook zonder die header geven.
Authorizationmag alleen inheadersstaan zolangauthvan de servernoneis, zoals hierboven (De headerAuthorization).Proxy-Authorization,Cookie, een header die Core of het transport zelf zet en de header waarin het eigenauthvan de server wordt verstuurd, worden altijd geweigerd (422opheaders).- Een
{@naam}in de URL geeft422opcall_variables.
Een PATCH die headers, install_values of call_variables noemt, vervangt dat veld in zijn
geheel.
De waarden meesturen¶
Stuur de waarden mee in tool_variables: een plat object van namen naar strings, getallen of
booleans.
curl -s -X POST "$CORE_URL/responses" \
-H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
-d '{"model": "<een model-id>",
"input": "Welke bestellingen staan nog open?",
"tools": [{"type": "tool", "name": "api__orders"}],
"tool_variables": {"account_id": "A-10442",
"customer_token": "fake-token-for-docs-0001"}}'
Hetzelfde veld bestaat op:
| Waar | Hoe |
|---|---|
POST /responses en POST /messages |
tool_variables naast de rest van het verzoek, ook voor een achtergrondbeurt |
POST /tools/{name}/call |
{"arguments": {...}, "tool_variables": {...}}, gecontroleerd tegen die ene tool (Een tool rechtstreeks aanroepen) |
| Een planning | tool_variables in de opgeslagen request; elke keer dat de planning afgaat, gaan ze mee |
| Een evaluatiescenario | tool_variables op het scenario, meegestuurd bij elke stap; alleen waarden die geen geheim zijn |
| Een toolset als MCP-server | in params._meta van elke aanroep (hieronder) |
Een workflowrun krijgt zijn waarden bij de start in variables; zie Scripts, workflows en
aliassen.
Wat er met een waarde gebeurt¶
- Het model ziet hem nooit. De waarden staan niet in de context, niet in de beschrijving van een tool en niet in zijn argumenten.
- Elke tool krijgt alleen wat hij declareert. Een tool die geen aanroepvariabelen declareert, krijgt er geen; geen enkele tool ziet de hele set van het verzoek.
- Een naam die geen tool declareert, wordt genegeerd. Je kunt dus dezelfde set meesturen,
ook als het beleid van je sleutel of een toolset een tool uit de beurt haalt. De
trace noemt de genegeerde namen in
interpretation.tool_variables_ignored, en bij elke toolaanroep de namen die die tool kreeg. Een waarde staat nooit in een trace, een logregel of de audit. - Het antwoord herhaalt ze niet. Het opgeslagen antwoord en
GET /responses/{id}bevatten geentool_variables.
Een waarde die ontbreekt of niet past¶
Core controleert tool_variables tegen de declaraties van alle tools die de beurt aanbiedt, voordat
er een model wordt aangeroepen. Er gaat dus niets naar het model en er wordt niets in rekening gebracht als een
waarde niet klopt. Een tool die het beleid van je sleutel achterhoudt, telt niet mee.
Core weigert:
- een verplichte variabele zonder waarde en zonder
default; - een waarde die niet bij de declaratie past: het verkeerde type, of niet in de
enum; - een waarde die niet past op de plek waar hij komt: een
{of}, een stuurteken in een header, of.of..in het pad van een URL.
De melding noemt de variabele en de tool. Op POST /responses is dat een 400 in de vorm van
OpenAI:
{
"error": {
"message": "api__orders requires customer_token.",
"type": "invalid_request_error",
"param": "tool_variables.customer_token",
"code": "invalid_request"
}
}
POST /messages antwoordt 400 in de vorm van Anthropic, met
tool_variables.customer_token: api__orders requires customer_token. als bericht.
POST /tools/{name}/call antwoordt 422 met tool_variables.customer_token als field in de lijst
errors (Foutformaat).
Een achtergrondbeurt controleert zijn waarden wanneer hij begint: ontbreekt er een, dan mislukt de run voordat er een model wordt aangeroepen, met dezelfde zin als fout.
Geneste agents, taken en workflows¶
Een beurt geeft zijn waarden door aan wat hij zelf start, omdat de aanroeper dezelfde blijft:
- een agent die als tool wordt aangeroepen en een agent die als taak wordt gestart, krijgen de hele set en controleren hem tegen hun eigen tools;
- een tool die als taak op de achtergrond draait, houdt het deel dat hij declareert;
- een workflow die vanuit een beurt als taak start, houdt de waarden die hij zelf declareert;
core__call_tool, waarmee een beurt een andere tool aanroept, draagt de waarden van de beurt mee;- een tool achter de toolrouter krijgt zijn eigen deel, net als elke andere tool.
Het model kan zelf geen aanroepvariabelen zetten. Een verzoek dat een core__-tool namens het model
naar Core stuurt, mag geen tool_variables bevatten; Core weigert het. builtin__subagent biedt
geen tools aan en heeft dus niets door te geven.
Een toolset via MCP¶
Bied je een toolset als MCP-server aan, dan heeft de client
geen veld voor tool_variables. Hij stuurt de waarden per aanroep mee in
params._meta["artific/tool_variables"]:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "api__orders",
"arguments": {"status": "open"},
"_meta": {"artific/tool_variables": {"account_id": "A-10442",
"customer_token": "fake-token-for-docs-0001"}}
}
}
Core controleert de aanroep tegen die ene tool, zoals bij POST /tools/{name}/call. De lijst met
tools toont ook de tools die een variabele vereisen. Ontbreekt een verplichte variabele, past een
waarde niet, of is _meta geen plat object, dan antwoordt de aanroep zoals MCP een mislukte tool
meldt: de zin van de weigering met isError, voordat er iets draait of in rekening wordt gebracht.
Geheime waarden¶
Een API-koppeling en een MCP-server kunnen beide soorten waarden geheim houden.
Een geheime aanroepvariabele is een eigenschap met x-secret: true: een string van hoogstens
8.192 tekens, zonder default en zonder enum, omdat iedereen die de tool kan lezen die leest.
Een geheime invulwaarde is {"type": "secret", "value": "..."}, voor een endpoint dat naast
auth nog een credential nodig heeft. Voor een API-koppeling staat hij beschreven onder Waarden die
je één keer vastlegt; op een MCP-server werkt hij hetzelfde:
- je schrijft hem één keer en leest hem nooit terug:
GETantwoordt{"type": "secret", "has_value": true, "description": "..."}; - een
PATCHdieinstall_valuesvervangt, geeft elk geheim opnieuw, of{"$keep": true}om het bewaarde te houden; - een deployment zonder sleutel om te versleutelen antwoordt
503op een body met een geheim.
Voor beide soorten geldt:
- Alleen in een headerwaarde of een string in de body, nooit in de URL of een querywaarde, want die komen in logbestanden van proxy's en servers terecht. Op een MCP-server alleen in een headerwaarde.
- Core maskeert ze in resultaten. Voordat het model of de trace een resultaat ziet, vervangt
Core elke letterlijke echo van een geheime waarde van 8 tekens of meer door
[secret]. Een kortere waarde, of een waarde die het endpoint heeft bewerkt (in base64 gecodeerd, gehasht, in stukken), herkent Core niet. Stuur een geheim dus niet terug in je antwoord. - Versleuteld opgeslagen. Een achtergrondrun en een planning bewaren een geheime waarde
versleuteld; de run gooit hem weg zodra hij klaar is. Een planning geeft de namen in
tool_variable_secretsterug als{"has_value": true}en laat ze weg uitrequest.tool_variables; een wijziging die zo'n naam weglaat, houdt de bewaarde waarde. Een achtergrondverzoek met een geheim op een deployment zonder sleutel om te versleutelen geeft503. - Niet in een evaluatiescenario. Een scenario is testdata die iedereen met toegang tot de suite
leest. Een waarde voor een geheime naam geeft
422optool_variables.<naam>. Core beschouwt een naam als geheim zodra een API-koppeling of MCP-server van je organisatie hemx-secretdeclareert. - Scripts, workflows en aliassen accepteren geen geheimen. Hun registratie weigert een
x-secretaanroepvariabele en eensecretinvulwaarde met422. Een tool achter een workflow of alias die een geheim nodig heeft, krijgt het met het verzoek dat die tool bereikt.
De header Authorization¶
Het sjabloon van een API-koppeling en de headers van een MCP-server mogen de header
Authorization alleen schrijven als het eigen credential van de tool, auth, none is. Zo werken
beide voorbeelden hierboven: "Bearer {@customer_token}" met een geheime aanroepvariabele. Naast een
credential zou het een tweede credential zijn, en dat geeft 422, op request bij een koppeling en
op headers bij een MCP-server. Een koppeling of server die je via een publicatie deelt en waarvan
het credential meereist of door de installateur wordt ingevuld, telt als een tool met een
credential.
Cookie en Proxy-Authorization worden altijd geweigerd, net als de header waarin auth wordt
verstuurd. Er is geen manier om auth per verzoek te vervangen: een credential per verzoek is een
geheime aanroepvariabele, op de plek die de maker van de tool in het sjabloon zette.
Scripts, workflows en aliassen¶
Ook deze soorten declareren install_values en call_variables, alleen zonder geheimen:
| Soort | Invulwaarde | Aanroepvariabele |
|---|---|---|
| Script | het bestand dat ARTIFIC_INSTALL noemt, alleen-lezen |
het bestand dat ARTIFIC_VARIABLES noemt, met alleen de variabelen die de versie declareert |
| Workflow | install.<naam> in een expressie |
run.variables.<naam> in een expressie; een toolstap geeft ze door aan zijn tool |
| Alias | een vast argument dat precies "{$naam}" is |
een vast argument dat precies "{@naam}" is |
Een workflowrun krijgt zijn waarden bij de start in variables (POST /workflows/{id}/runs), niet in
tool_variables; een waarde die niet past geeft 422 op variables.<naam>. Een toolstap waarvan de
tool een variabele vereist die de run niet heeft, eindigt met de code variable_missing:<naam>.
Met een alias geef je elke andere tool een waarde per verzoek, zonder dat het model hem ziet: een
vast argument "{@customer_id}" geeft bijvoorbeeld een zoektool een filter per klant.
Limieten¶
| Wat | Limiet |
|---|---|
Namen in tool_variables |
64 |
| Eén string | 4.096 tekens; 8.192 voor een geheim |
| Het hele object, als compacte JSON | 64 KiB |
call_variables op één versie |
64 |
Een verzoek met te veel namen, te veel bytes in totaal of een string van meer dan 8.192 tekens
wordt geweigerd op tool_variables voordat er een tool wordt bekeken. Een gewone string van 4.097
tot 8.192 tekens wordt geweigerd wanneer de tools van de beurt worden gecontroleerd, op
tool_variables.<naam>, met de tool die hem declareert; voor een naam die geen tool declareert,
wordt hij genegeerd.
Je deployment kan andere limieten hebben ingesteld.