Skip to main content
Version: Current

Sources: APIs & integrations

The station's tools: the tenant's APIs, and the catalogue that search queries.

The APIs​

apis:
- name: cuisine
openapi_url: https://api.teranga.example.sn/openapi.json
base_url: https://api.teranga.example.sn
auth: {type: api_key, key_name: X-API-Key, key_location: header, key_env: TERANGA_KEY}
operations:
- {id: getMenu, access: read}
- {id: getDeliveryOptions, access: read}
- {id: checkDeliverable, access: read}
- {id: getDeliveryPrice, access: read}
- {id: placeOrder, access: write}
- {id: createDelivery, access: write, reversible: false}
- {id: deleteCustomer, access: write, exposed: false}
  • operations is an allowlist. An operation that is not in it cannot be reached, even if the OpenAPI describes it. The list is required and never empty. Do not list a write that nothing uses, except as exposed: false to document it.
attributeeffect
idthe OpenAPI operationId. The same operation declared twice is refused.
accessrequired. read changes nothing at the tenant and runs at once. write changes something and is reserved: only a submit, the submit guard (submit_guard.validate) or the sign-in (to send and check a code) calls it. Declared, never guessed from the HTTP verb: a search is often a POST.
reversibleon a write only: the operation of the same API that undoes it, or false. false on an operation a submit calls: the MCP door announces the submit as destructive. Nothing else reads it yet.
exposed: falselisted, checked against the OpenAPI at provisioning, but never reachable. Naming it elsewhere is refused.
  • Core refuses the contradictions at load. A write called at once (by a skill's invoke, a check or update guard) would change the tenant's record with no submit and no person to confirm. A submit that goes through a read files nothing, and the receipt would say otherwise.
  • The key never appears in the file. key_env names an environment variable. The model does not see it and does not send it: so it cannot widen what the key allows.
  • Separate reads and writes into two entries when the tenant has two keys, or simply so that the boundary shows in the config:
apis:
- name: rh-lecture
operations:
- {id: getTimesheets, access: read}
- {id: getOvertimeReport, access: read}
auth: {type: api_key, key_name: X-RH-Key, key_location: header, key_env: RH_READ_KEY}
# …
- name: rh-ecriture
operations:
- {id: approveTimesheets, access: write}
auth: {type: api_key, key_name: X-RH-Key, key_location: header, key_env: RH_WRITE_KEY}
# …
One identity per key

Today, an API's key is the station's key: everyone talks to the tenant under the same identity. Two managers using the same station are, for the HR tool, the same manager. Per-person identity comes with the target version (on_behalf_of: identity).

The catalogue​

catalog:
from_skill: takeMealSelection # the skill with kinds that returns the whole catalogue
mode: live # live | indexed
  • live: each search queries the tenant's search (under the query_arg parameter), and shows its results in its order. Always up to date, no index.
  • indexed: the catalogue is read once and indexed, then read again when the station is provisioned or resynchronised; nothing watches the source. Semantic search; the skill must return the whole catalogue, without pagination.