Agents and expservices
This page is for developers who want an agent to use administration functions beyond reading content. The extension expservices, part of the default distribution, turns those functions into over a thousand named services. Its guide walks through calling them; this page adds what matters for an agent.
Contents
- How a service call looks
- A token for the agent
- The catalog as a tool list
- Rules every service follows
- One declaration, two channels
How a service call looks
A service is called by name, exp<domain>::<method>, through the ezjscore call interface, and answers JSON:
curl -s 'https://example.com/ezjscore/call/expsession::whoami?ContentType=json'Inside the ezjscore envelope every answer has one shape: {"ok":true,"data":...,"meta":{...}} or
{"ok":false,"error":{"code":403,"message":"..."}}. Lists are paged and meta carries total, offset, limit,
count and has_more. One shape makes it easy for an agent's code to tell success from refusal.
A token for the agent
A session cookie expires and needs a form token for every write. For an agent, use a personal token:
- Sign in as the agent's own account (never a person's).
- Create a token with the service
expsession::tokenCreate(a name and a lifetime in days). It is shown once,expt_followed by 48 hex characters; only its hash is stored. - The agent sends it as
Authorization: Bearer <token>, orX-Exp-Token: <token>where a proxy drops the first header. Writes still need POST, but no form token. - List and revoke tokens with
expsession::tokenListandexpsession::tokenRevoke.
An unknown, revoked or expired token, or one of a disabled user, answers 401 on every service, so the agent notices
that its token died. A token cannot create tokens. Create, revoke and refusals are recorded in the audit trail
(access.expservices.token.*).
The catalog as a tool list
The catalog lists every service with its summary, access rule, arguments and an example call:
cd extension/expservices/bin
./expservices-client.sh catalog node | grep -E '"method"|"summary"'Each entry says access (public, user, or a [module, function] policy) and write (true for services that
change something). For an agent:
- Build the model's tool list from the catalog entries you choose, not from all of them.
- Leave out every entry with
write: trueuntil the read workflow is proven. - Give the account only the policies the chosen services need.
Setup > RAD (/setup/rad) lists the same catalog in the administration.
Rules every service follows
From the guide: 401 without login, 403 without the policy; a write needs POST (and a form token with a session) and
records service.<domain>.<method> in the audit trail; large operations are routed to content jobs. A failing policy
answers error 403, a bad argument error 422 or error 400 with the reason.
One declaration, two channels
A service is declared once in its domain class. That declaration makes it:
| Channel | Name | Who calls it |
|---|---|---|
| An HTTP endpoint | ezjscore/call/exp<domain>::<method> | People, apps, agents with a token |
A tool of Exponential Intelligence (only when the service opts in with 'ai' => true and is a read service) | a tool name derived from the domain and method | The assistant, as the editor, with expai/services (Service tools) |
Each channel runs with its caller's permissions. See Remote services with expservices for writing a service domain of your own.
Related pages
- Choosing an interface for an agent
- Credentials for agents
- Backend services over ezjscore
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.