Agent servers
An agent server is the Python process that runs agents inside your enterprise: a FastAPI application served by Uvicorn, fully asynchronous, with exactly one worker. Run one on a laptop or several behind a load balancer; any agent server can serve any request. This page covers the command line, the addresses an agent server serves, and how agent servers are configured.
The command line
Options on the search2o command line are passed through to Uvicorn, so the Uvicorn options for the address, the port and TLS all work as Uvicorn documents them. The following options are refused because the agent server runs as exactly one worker per process:
--reload --reload-dir --reload-include --reload-exclude --reload-delay
--factory
--workersFor more than one worker's worth of capacity, run more agent servers.
What an agent server serves
By default an agent server listens on 127.0.0.1:9020 and serves:
| Address | What is there |
|---|---|
http://127.0.0.1:9020/ui | The UI |
http://127.0.0.1:9020/openapi.json | The OpenAPI schema |
http://127.0.0.1:9020/docs | Swagger UI |
http://127.0.0.1:9020/redoc | ReDoc |
All of these paths are settings in the agent server's configuration, described next.
Named agent server configurations
The Agent servers page holds one or more named configurations. The one named default is required, and an agent server uses it unless told otherwise. To run an agent server under another configuration, append the name to the license key: SEARCH2O_LICENSE_KEY=your-license-key/edge starts the agent server with the configuration named edge. Separate configurations suit agent servers that differ in what they serve, for example one that serves the UI and one that answers only REST calls.
What a configuration sets
| Field | Type | Default | Description |
|---|---|---|---|
uiPath | string | "/ui" | The path the bundled Search2o application is served at. Leave it empty to not serve it at all. |
routes | list of "owner" | "admin" | "dev" | "user" | "auth" | "exec" | "reports" | The list of routes to serve. | |
connectPageUrl | string | The page where a user approves an integration's request for access. Leave it empty and it follows the application path above, which is what keeps the two in step. Set a page under that path for an application of your own, such as connect, or a full address for one hosted elsewhere, such as https://ui.example.com/connect. Whatever is set must point at where the application is really served. The request is added to it as a query parameter named c. | |
allowCrossOrigin | list of string | ['*'] | Other origins allowed to call this API, such as https://ui.example.com. |
docsUrl | string | "/docs" | Where the API documentation is served. |
redocUrl | string | "/redoc" | Where the ReDoc documentation is served. |
openapiUrl | string | "/openapi.json" | Where the OpenAPI schema is served. |
logs | object of string → JSON value | Logging configuration for the agent server. | |
cloudPool | ConnectionPoolModel | How this agent server connects to Search2o Cloud. It carries connection settings only: it is deliberately not one of the API connection pools, and it has no certificate fields, so nothing configured for an agent can change how this server reaches Search2o Cloud. A server behind a proxy that re-signs TLS trusts that proxy through the SSL_CERT_FILE environment variable, which is where a machine-wide trust setting belongs. Changing any of this needs an agent server restart. | |
uiConfig | object of string → JSON value | A free form JSON configuration that is sent to the UI from the getUiConfig call. | |
shutdownGrace | integer | 10 | When this agent server shuts down, how many seconds agents that are still running get to finish before they are stopped. Changing this needs an agent server restart. |
These settings are read once, at startup, so a change takes effect when the agent server restarts. The logs object is a standard Python logging configuration dictionary. The UI path may point anywhere the agent server can read; leave it empty to serve no UI. The documentation paths can be moved or set to nothing to switch the interactive API documentation off.
The UI's settings
The uiConfig object holds the settings the UI reads from the agent server when the page loads. Each agent server configuration has its own, so two agent servers in one account can serve the UI with different search behaviors or a different tag. A key that is missing takes the default below. A change takes effect when the agent server restarts and each user reloads the UI.
"uiConfig": {
"apiTimeoutSeconds": 90,
"toastDurationSeconds": 10,
"search": {
"tag": "",
"searchBehavior": "executeTopMatch",
"followupBehavior": "executeTopMatch"
}
}| Key | Meaning | Default |
|---|---|---|
apiTimeoutSeconds | Timeout, in seconds, for REST calls from the UI. Keep it above 60: submitting a description indexes the agent, which takes 15 to 30 seconds. | 90 |
toastDurationSeconds | How long a notification stays visible in the UI, in seconds. | 10 |
search.tag | The tag the UI sends with every search, follow-ups included. Empty searches every tag. | "" |
search.searchBehavior | What the UI does with the matches of a new search; see Search behavior. | executeTopMatch |
search.followupBehavior | What the UI does with the matches of a follow-up in a conversation. | executeTopMatch |
Startup errors
Problems found at startup are written to the agent server's log. An allowlist entry the agent server cannot import is skipped, and the rest of the allowlist loads. A hook or an LLM adapter that cannot be loaded stops the agent server from running agents until it is fixed and the agent server restarted.
Running many agent servers
The agent server is stateless, so containerize it and run it load balanced; nothing more is needed. Every agent server picks up a configuration or profile change before its next agent run, so agent servers never drift from each other; see Runtime sync. The exceptions are the settings on this page, which need a restart, and the license key: after a rotation, every agent server is restarted with the new key. When an agent is deleted, every agent server drops its cached copy at its next configuration refresh.
When an agent server stops, the agents still running get shutdownGrace seconds to finish before they are stopped.
Health
GET /health is answered by the agent server itself, without sign-in, and is the call for a load balancer or a monitor to use. It reaches nothing outside the agent server, so its response time reflects that agent server's own health. See Agent server sizing.

