Skip to main content
A custom source puts your own system in the Company Brain: an internal wiki, a ticketing system, a document store behind your own API. Agents search it and read from it like any other source, with citations, scope, timeout, cache and the access log. An admin adds it in Platform > Agents > Knowledge; this page is for the engineers who build it. Your system decides what each person may see. Every call xpander makes to it carries a short-lived token, signed by your xpander install, that names the person who asked: their user id, email and groups. Your system verifies the token and answers only what that person may open, so an item it hides from someone never reaches them. There are two ways to connect a system:

The REST contract

Your system answers two POST requests under the base URL. Both take and return JSON. The full OpenAPI 3.1 description is below.
How admins scope a custom source by ref prefix and by path is under Custom source settings. Answer with the items this person may see, best match first:

Read

text is plain text or Markdown; xpander keeps the first 200,000 characters. title, url, modified and path are optional.

Status codes

The identity token

Every call carries X-Xpander-Identity: a JSON Web Token signed with ES256 by your xpander install. Its header names the signing key (kid) and has typ: xpander-brain-identity+jwt. The public keys are at the JWKS URL shown on the source: https://api.xpander.ai/.well-known/brain-identity-jwks.json on xpander cloud, and your own API host’s /.well-known/brain-identity-jwks.json on a self-hosted install. Cache the key set and fetch it again when a token names a kid you have not seen. Each install has its own signing key, and it is used for nothing but this token. Verify the signature, aud, exp and iss on every call, then apply your own permissions with sub, email and groups.

A minimal REST source

A complete source in Python (FastAPI) that verifies the token with person() above and filters by group:
Run it behind TLS (uvicorn app:app behind your HTTPS proxy), use its base URL as the source’s Endpoint, and a person outside Finance never gets the forecast.

The MCP option

Pick an MCP server that is already in the Skills registry. xpander calls it over streamable HTTP: initialize, then tools/call on the Search tool with {"query": "...", "limit": 25, "scope": {...}} and on the Read tool with {"ref": "..."}. The functions answer in the same shapes as the REST contract: the search answer is {"items": [...]} and the read answer is {"title", "text", "url", "modified"}. xpander reads structuredContent when the answer has it, and otherwise parses the text content as JSON; a read may also answer plain text, which becomes the item’s text. A call that answers isError counts as a failure. The server’s authentication is the one set in the Skills registry: an API key, custom headers, each person’s OAuth sign-in (each person signs in once, from the source’s Connection tab or from Settings > Knowledge), or the person’s SSO token. Every call also carries X-Xpander-Identity, so the server can apply its own permissions even with a shared key. A server that supports only the older SSE transport cannot be used as a source.

Network rules

xpander calls a custom source from your install:
  • HTTPS only. On xpander cloud the endpoint must be reachable on the public internet; private, loopback and cloud metadata addresses are refused.
  • Self-hosted installs may call endpoints inside your network over HTTPS. Plain http:// is accepted only when the install sets BRAIN_CUSTOM_SOURCES_ALLOW_HTTP=true on agent-controller, and only for an address inside your network. Metadata addresses are never called.
  • No redirects to another host. A redirect to the same host with 307 or 308 is followed; any other redirect fails the call. Use the final URL as the endpoint.
  • Size and time. A search answer may be up to 2 MB and a read answer up to 5 MB. A call that takes longer than the source’s timeout is dropped for that question.
  • The calls do not go through an HTTPS_PROXY.
Air-gapped installations. Custom sources are the live sources an air-gapped installation can use: your system lives in your network, the JWKS is served by your own xpander API, and nothing leaves the installation. Add source offers Custom there.

Troubleshooting

A token that fails to verify on your side is usually one of: the JWKS fetched from another install’s API host, aud compared with something other than the source’s id, or a clock more than 30 seconds off. For the messages Test connection shows, see A custom source fails Test connection.

OpenAPI description