Server Configuration
The MCP server supports configuration through a YAML file, command-line flags, and environment variables.
Configuration Priority
The server applies configuration values in the following order from highest to lowest priority:
- Command-line flags (highest priority).
- Environment variables.
- Configuration file.
- Built-in defaults (lowest priority).
Configuration File
File Locations
The server searches for its configuration file in the following order:
- The path specified via the
-configflag. - The per-user config directory at
~/.config/pgedge/ai-dba-server.yamlon Linux (honouring$XDG_CONFIG_HOME),~/Library/Application Support/pgedge/ai-dba-server.yamlon macOS, and%AppData%\pgedge\ai-dba-server.yamlon Windows. /etc/pgedge/ai-dba-server.yaml(system-wide).
If -config is set and the file is missing, the
server exits with an error. If -config is not set
and none of the default locations contain a
configuration file, the server uses built-in defaults
silently. The server no longer searches the binary
directory or the current working directory. The same
search paths apply to secret_file discovery for
ai-dba-server.secret; however, secret discovery is
not silent. If no secret_file is set in the YAML and
no ai-dba-server.secret file is present at any
search path, the server exits with an error at
startup.
Example Configuration
A complete example configuration file is available at examples/ai-dba-server.yaml in the project repository.
#=====================================================
# HTTP SERVER CONFIGURATION
#=====================================================
http:
# Address to listen on (host:port or :port)
address: ":8080"
# TLS/HTTPS Configuration
tls:
enabled: false
# cert_file: "/etc/ai-workbench/certs/cert.pem"
# key_file: "/etc/ai-workbench/certs/key.pem"
# chain_file: "/etc/ai-workbench/certs/chain.pem"
# Trusted reverse proxies (CIDR ranges)
# trusted_proxies:
# - "10.0.0.0/8"
# - "172.16.0.0/12"
# CORS origin for cross-origin deployments
# cors_origin: "https://workbench.example.com"
# Authentication Configuration
auth:
max_failed_attempts_before_lockout: 10
max_user_token_days: 0
rate_limit_window_minutes: 15
rate_limit_max_attempts: 10
# Local username and password login
local:
enabled: true
# Federated (OpenID Connect) login
# oidc:
# enabled: true
# issuer: "https://idp.example.com"
# client_id: "pgedge-workbench"
# client_secret_file: "/etc/pgedge/oidc-client-secret.txt"
# redirect_url: "https://workbench.example.com/api/v1/auth/oidc/callback"
audit_retention_days: 90
#=====================================================
# CONNECTION SECURITY
#=====================================================
connection_security:
allow_internal_networks: false
# allowed_hosts:
# - "db.example.com"
# - "192.168.1.0/24"
# blocked_hosts:
# - "169.254.169.254"
#=====================================================
# DATABASE CONNECTION
#=====================================================
database:
host: "localhost"
port: 5432
database: "ai_workbench"
user: "postgres"
# password: ""
# password_file: "/etc/pgedge/password.txt"
sslmode: "prefer"
pool_max_conns: 20
pool_min_conns: 0
pool_max_conn_idle_time: "30m"
statement_timeout: "30s"
#=====================================================
# EMBEDDING GENERATION
#=====================================================
embedding:
enabled: false
provider: "ollama"
model: "nomic-embed-text"
ollama_url: "http://localhost:11434"
# voyage_api_key_file: "~/.voyage-api-key"
# openai_api_key_file: "~/.openai-api-key"
# gemini_api_key_file: "~/.gemini-api-key"
#=====================================================
# LLM CONFIGURATION (Chat Proxy and AI Analysis)
#=====================================================
llm:
provider: "anthropic"
model: "claude-sonnet-5"
# anthropic_api_key_file: "~/.anthropic-api-key"
# openai_api_key_file: "~/.openai-api-key"
# gemini_api_key_file: "~/.gemini-api-key"
ollama_url: "http://localhost:11434"
max_tokens: 4096
temperature: 0.7
max_iterations: 50
compact_tool_descriptions: "auto"
# reasoning_effort: "medium"
# prompt_caching: "auto"
# extra_body: {}
#=====================================================
# KNOWLEDGEBASE CONFIGURATION
#=====================================================
knowledgebase:
enabled: false
# database_path: "/usr/share/pgedge/pgedge-ai-kb/kb-ollama-nomic-embed-text.db"
embedding_provider: "ollama"
embedding_model: "nomic-embed-text"
embedding_ollama_url: "http://localhost:11434"
#=====================================================
# CHAT MEMORY CONFIGURATION
#=====================================================
memory:
enabled: true
#=====================================================
# BUILT-IN TOOLS, RESOURCES, AND PROMPTS
#=====================================================
builtins:
tools:
query_database: true
get_schema_info: true
similarity_search: true
execute_explain: true
count_rows: true
list_probes: true
describe_probe: true
query_metrics: true
list_connections: true
get_alert_history: true
get_alert_rules: true
get_metric_baselines: true
get_blackouts: true
get_timeline_events: true
query_datastore: true
describe_datastore: true
generate_embedding: true
search_knowledgebase: true
store_memory: true
recall_memories: true
delete_memory: true
resources:
system_info: true
connection_info: true
#=====================================================
# PATHS AND DATA DIRECTORIES
#=====================================================
# secret_file: "/etc/ai-workbench/server.secret"
# custom_definitions_path: "/etc/ai-workbench/defs.yaml"
# data_dir: "/var/lib/ai-workbench/data"
Command-Line Flags
General Options
| Flag | Description |
|---|---|
-config string |
Path to configuration file |
-debug |
Enable debug logging |
-data-dir string |
Data directory for auth and conversations |
-trace-file string |
Path to MCP trace file |
HTTP Server Options
| Flag | Description |
|---|---|
-addr string |
HTTP address (default: :8080) |
-tls |
Enable TLS/HTTPS |
-cert string |
Path to TLS certificate file |
-key string |
Path to TLS key file |
-chain string |
Path to TLS certificate chain |
Database Connection Options
| Flag | Description |
|---|---|
-db-host string |
Database host |
-db-port int |
Database port |
-db-name string |
Database name |
-db-user string |
Database user |
-db-password string |
Database password |
-db-password-file string |
Path to DB password file, read at start-up only; overrides the configured password |
-db-sslmode string |
SSL mode |
Token Management Options
| Flag | Description |
|---|---|
-add-token |
Add a new service token |
-remove-token string |
Remove token by ID or hash |
-list-tokens |
List all service tokens |
-token-note string |
Annotation for new token |
-token-expiry string |
Token expiry duration |
-user string |
Owner username for the token |
User Management Options
| Flag | Description |
|---|---|
-add-user |
Add a new user |
-update-user |
Update an existing user |
-delete-user |
Delete a user |
-list-users |
List all users |
-enable-user |
Enable a user account |
-disable-user |
Disable a user account |
-add-service-account |
Add a service account |
-username string |
Username for user commands |
-password string |
Password for user commands |
-full-name string |
Full name for the user |
-email string |
Email address for the user |
-user-note string |
Annotation for new user |
Group Management Options
| Flag | Description |
|---|---|
-add-group |
Add a new RBAC group |
-delete-group |
Delete an RBAC group |
-list-groups |
List all RBAC groups |
-list-members |
List the members of a group |
-add-member |
Add a user or group to a group |
-remove-member |
Remove a member from a group |
-group string |
Group name for group commands |
-group-description string |
Group description for add-group |
-member-group string |
Member group for nesting |
-set-superuser |
Set superuser status |
-unset-superuser |
Remove superuser status |
Privilege Management Options
| Flag | Description |
|---|---|
-grant-privilege |
Grant an MCP privilege |
-revoke-privilege |
Revoke an MCP privilege |
-grant-connection |
Grant connection access |
-revoke-connection |
Revoke connection access |
-list-privileges |
List MCP privileges |
-show-group-privileges |
Show group privileges |
-register-privilege |
Register a new privilege |
-privilege string |
MCP privilege identifier |
-privilege-type string |
Privilege type |
-privilege-description string |
Description |
-connection int |
Connection ID |
-access-level string |
Access level (default: read) |
Token Scope Options
| Flag | Description |
|---|---|
-scope-token-connections |
Set connection scope |
-scope-token-tools |
Set MCP tool scope |
-clear-token-scope |
Clear all scope restrictions |
-show-token-scope |
Show current token scope |
-token-id int |
Token ID for scope commands |
-scope-connections string |
Connection ID list |
-scope-tools string |
Tool name list |
Audit Log Options
The audit log records every change to users,
groups, tokens and privileges; the
Audit Log
document describes the events and how to read
them. The following table describes the flags
that read and verify the log, along with
-rechain-audit-log, which either re-hashes an
inherited log or re-anchors one that no longer
verifies; a re-anchor leaves the existing events
as they are and appends an anchor event:
| Flag | Description |
|---|---|
-list-audit |
List RBAC audit log events |
-verify-audit-log |
Verify the audit log hash chain |
-rechain-audit-log |
Re-hash an inherited audit log, or re-anchor one that no longer verifies |
-confirm-rechain |
Confirm -rechain-audit-log without an interactive prompt |
-previous-secret-file string |
Secret file the older audit events were written under, needed by -confirm-rechain to re-anchor them |
-audit-actor string |
Filter events by actor name |
-audit-action string |
Filter events by action |
-audit-target-type string |
Filter events by target type |
-audit-target-id int |
Filter events by target ID |
-audit-outcome string |
Filter events by outcome |
-audit-since string |
Earliest event time to show |
-audit-until string |
Latest event time to show |
-audit-limit int |
Maximum events to show (default: 50) |
-json |
Emit output as one JSON object per line |
Configuration Sections
HTTP Server (http)
| Option | Type | Default | Description |
|---|---|---|---|
address |
string | :8080 |
Listen address |
tls.enabled |
bool | false |
Enable TLS |
tls.cert_file |
string | Certificate file | |
tls.key_file |
string | Private key file | |
tls.chain_file |
string | Certificate chain | |
trusted_proxies |
list | [] |
Trusted proxy CIDRs; required behind a reverse proxy when OIDC login is enabled |
cors_origin |
string | "" |
Allowed CORS origin |
hsts_enabled |
bool | false |
Send the Strict-Transport-Security header |
auth.max_failed_attempts_before_lockout |
int | 10 |
Lock after N failures (0 disables); restart required |
auth.max_user_token_days |
int | 0 |
Max token lifetime |
auth.rate_limit_window_minutes |
int | 15 |
Rate limit window |
auth.rate_limit_max_attempts |
int | 10 |
Max attempts per window |
auth.local.enabled |
bool | true |
Enable username and password login |
auth.oidc.enabled |
bool | false |
Enable federated login |
auth.oidc.issuer |
string | Identity provider issuer URL | |
auth.oidc.client_id |
string | OAuth 2.0 client identifier | |
auth.oidc.client_secret |
string | Inline client secret | |
auth.oidc.client_secret_file |
string | File holding the client secret | |
auth.oidc.redirect_url |
string | Callback URL registered at the provider | |
auth.oidc.scopes |
list | [openid, email, profile] |
Scopes requested at the provider |
auth.oidc.username_claim |
string | email |
Claim used as the username |
auth.oidc.display_name_claim |
string | name |
Claim used as the display name |
auth.oidc.groups_claim |
string | groups |
Claim carrying group membership |
auth.oidc.button_label |
string | Sign in with your identity provider |
Federated login button label |
auth.oidc.provision_users |
bool | false |
Create an account on first login |
auth.oidc.allowed_email_domains |
list | [] |
Permitted verified email domains |
auth.oidc.superuser_group |
string | Provider group granting superuser | |
auth.oidc.group_map |
map | {} |
Provider group to Workbench group map |
auth.oidc.allow_unprefixed_state_cookie |
bool | false |
Accept an unprefixed login state cookie behind a proxy |
auth.oidc.allow_api_tokens |
bool | false |
Let federated users own API tokens |
auth.oidc.auth_params |
map | {} |
Extra authorisation request parameters |
Authentication (auth)
The auth section governs both login methods. Local
username and password login is on unless
auth.local.enabled is set to false, and federated
login is off unless auth.oidc.enabled is set to
true. The server refuses to start when neither
method is available.
While federated login is disabled, the server ignores
every auth.oidc.* option except auth_params, which
it still validates, and allow_api_tokens, which still
applies to accounts linked to a provider earlier. The
Single Sign-On guide
describes each option in full, along with registering
the Workbench at an identity provider and mapping
provider groups onto Workbench groups.
The server also refuses to start with federated login
enabled, an https auth.oidc.redirect_url,
tls.enabled set to false and an empty
trusted_proxies list. On that deployment the login
state cookie cannot use the __Host- name prefix, so a
sibling subdomain that can set cookies can log users in
as an attacker. Set trusted_proxies to the reverse
proxy's address, or set
auth.oidc.allow_unprefixed_state_cookie to true to
accept the risk.
The server likewise refuses to start, whether or not
federated login is enabled, when
auth.oidc.auth_params names a parameter the Workbench
sets itself, such as state or redirect_uri; the
Single Sign-On guide lists them, and gives the Google
example that needs access_type: offline.
| auth.audit_retention_days | int | 90 | Days to keep RBAC audit events (0 keeps forever) |
Warning
While auth.oidc.allow_api_tokens is false, the
default, an account that signs in through the
identity provider cannot create API tokens, and any
token such an account already owns is refused on use.
Switching it on lets those tokens keep working after
the person is removed at the identity provider,
until each token expires or is revoked, or the
Workbench account is disabled or deleted, because the
provider is never consulted when a token is used.
Use a local service account for automation instead.
CORS Origin (cors_origin)
The cors_origin option sets the value for the
Access-Control-Allow-Origin response header. The empty
default suits same-origin deployments, where the web
client and the server share an origin. The server omits
CORS headers entirely in that case.
Set cors_origin to an explicit origin when the web
client runs on a different origin than the server. For
example, use https://workbench.example.com as the
value. The server returns
Access-Control-Allow-Credentials: true so browsers can
attach session cookies to cross-origin requests.
The server rejects a cors_origin value of "*" at
startup when authentication is enabled. Browsers disallow
combining Access-Control-Allow-Origin: * with
Access-Control-Allow-Credentials: true per the Fetch
spec. Use an explicit origin, or leave the option empty
for same-origin deployments.
In the following example, the http section allows
cross-origin requests from a dedicated workbench host:
http:
address: ":8443"
cors_origin: "https://workbench.example.com"
auth:
local:
enabled: true
Connection Security (connection_security)
The connection security section controls SSRF protection for user-created database connections.
| Option | Type | Default | Description |
|---|---|---|---|
allow_internal_networks |
bool | false |
Allow RFC 1918 addresses |
allowed_hosts |
list | [] |
Always-permitted hosts |
blocked_hosts |
list | [] |
Always-blocked hosts |
Database (database)
| Option | Type | Default | Description |
|---|---|---|---|
host |
string | localhost |
Database host |
port |
int | 5432 |
Database port |
database |
string | postgres |
Database name |
user |
string | Database user (required) | |
password |
string | Database password | |
password_file |
string | DB password file (if password empty) |
|
sslmode |
string | prefer |
SSL mode |
pool_max_conns |
int | 20 |
Max pool connections |
pool_min_conns |
int | 0 |
Min pool connections |
pool_max_conn_idle_time |
string | 30m |
Max idle time |
statement_timeout |
string | 30s |
Server-side statement timeout |
The statement_timeout option bounds how long a single statement may
run on a datastore pool connection before PostgreSQL cancels it. The
server already cancels its own queries once the request that asked for
them has given up, but that cancellation is a request sent over the
same connection, so a lost cancel, or a backend that is not at a point
where it can be interrupted, leaves the query running and holding one
of the few pool connections; the server-side timeout is what actually
frees the connection. The default of 30s matches the longest deadline
the server grants a datastore query, so it rejects nothing that would
otherwise have completed. The value accepts any Go duration string,
such as 45s or 1m30s; 0 disables the timeout, which is not
recommended because a single runaway query can then starve the pool.
The pool_max_conns option sets the size of the datastore connection
pool that every API request shares. A single dashboard page load
issues more than twenty metrics requests at once, so a small pool makes
a page wait on itself and lets a few slow requests hold up the rest of
the API. The default of 20 leaves room for a second user; together
with the collector's default of 25 and the alerter's default of 10, it
uses 55 of the 97 connections that the PostgreSQL default
max_connections of 100 makes available to ordinary users. Raise the
datastore's max_connections before raising any of the three pools
past that total. The datastore pool is sized when the server starts,
so a change takes effect on restart rather than on a SIGHUP reload.
When the option is set explicitly, the same value also caps each
per-session pool that the server opens to a monitored database, and a
per-session pool opened after a SIGHUP reload uses the reloaded
value; when the option is unset, including when the database is
configured only through the -db-* command-line flags, those pools
use the connection library's default.
Embedding (embedding)
The provider option accepts voyage, openai, gemini, or
ollama. The model option accepts any model name the chosen
provider recognises; the server passes the name through rather than
checking a fixed list, so a new provider model works as soon as the
provider publishes the model. Leaving model empty selects the
default model for the provider. Google publishes
gemini-embedding-001 (the default, 3072 dimensions) and
gemini-embedding-2 (also 3072 dimensions); model availability varies
by Gemini API key tier, so run ListModels to verify which embedding
models a given key can access.
Because the model name is not restricted, an OpenAI-protocol-compatible
local model server such as llama.cpp or vLLM can supply embeddings:
set provider to openai, point openai_base_url at that server,
and set model to the name the server provides.
The configured model must not produce vectors with more than 4000
dimensions. The server stores chat memory embeddings as halfvec(4000)
and zero-pads each embedding to 4000 dimensions; 4000 is pgvector's
HNSW index limit for the halfvec type. The server rejects a model
that exceeds 4000 dimensions with a clear error rather than truncating
the vector. Storing embeddings as halfvec requires pgvector 0.7.0
or newer; upgrading an existing installation against an older pgvector
causes the embedding-column migration to fail.
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false |
Enable embeddings |
provider |
string | ollama |
Provider name |
model |
string | varies | Model name |
ollama_url |
string | http://localhost:11434 |
Ollama URL |
voyage_api_key_file |
string | Voyage API key path | |
openai_api_key_file |
string | OpenAI API key path | |
gemini_api_key_file |
string | Gemini API key path | |
voyage_base_url |
string | https://api.voyageai.com/v1/embeddings |
Voyage base URL |
openai_base_url |
string | https://api.openai.com/v1 |
OpenAI base URL |
gemini_base_url |
string | https://generativelanguage.googleapis.com |
Gemini base URL |
LLM Proxy (llm)
The LLM proxy is optional. When no valid API key is
configured for the chosen provider, the server
disables all AI features at startup. The web client
detects the server's capabilities through the
/api/v1/capabilities endpoint and hides all
AI-dependent UI elements. The hidden elements include
the AI Overview, Ask Ellie chat, alert analysis, chart
analysis, and server analysis. The system continues to
function as a monitoring tool without AI features.
For Ollama, a valid URL is sufficient because Ollama does not require an API key. For Anthropic, OpenAI, and Gemini, the corresponding API key file must contain a valid key.
The settings in this section govern every AI feature the server drives. The features include the Ask Ellie chat proxy, the AI Overview, and the server-info AI database analysis.
| Option | Type | Default | Description |
|---|---|---|---|
provider |
string | anthropic |
LLM provider |
model |
string | claude-sonnet-5 |
Model name |
anthropic_api_key_file |
string | Anthropic key path | |
openai_api_key_file |
string | OpenAI key path | |
gemini_api_key_file |
string | Gemini key path | |
ollama_url |
string | http://localhost:11434 |
Ollama URL |
max_tokens |
int | 4096 |
Max output tokens per response |
temperature |
float | 0.7 |
Sampling temperature; 0 is honoured |
max_iterations |
int | 50 |
Max tool-call iterations |
compact_tool_descriptions |
string | auto |
Tool description mode |
timeout_seconds |
int | 120 |
LLM HTTP request timeout |
anthropic_base_url |
string | https://api.anthropic.com/v1 |
Anthropic base URL |
openai_base_url |
string | https://api.openai.com/v1 |
OpenAI base URL |
gemini_base_url |
string | https://generativelanguage.googleapis.com |
Gemini base URL |
reasoning_effort |
string | Reasoning effort level | |
prompt_caching |
string | Prompt caching mode | |
extra_body |
mapping | Extra request body fields (OpenAI only) | |
custom_headers |
mapping | Headers sent to every provider | |
custom_headers_files |
mapping | Header names mapped to secret files | |
anthropic_custom_headers |
mapping | Headers sent to Anthropic only | |
openai_custom_headers |
mapping | Headers sent to OpenAI only | |
gemini_custom_headers |
mapping | Headers sent to Gemini only | |
ollama_custom_headers |
mapping | Headers sent to Ollama only |
Sampling Temperature (temperature)
Some models accept only their own default temperature;
these include claude-sonnet-5, the default model, and
OpenAI's GPT-6 models. When a model rejects the
configured temperature, the server resends the request
without the setting and omits the setting from later
requests. The model's own default then applies, so the
temperature option has no effect, and the server does
not log the change.
Output Token Budget (max_tokens)
The max_tokens option caps the number of output
tokens a model may generate for a single response.
The budget applies to the following AI features:
- The Ask Ellie chat proxy sends the budget with every chat request that the proxy forwards to a provider.
- The AI Overview applies the budget to the estate summary and to each scoped summary.
- The server-info AI database analysis applies the budget to the per-database descriptions.
The default value is 4096 tokens; a value less than
or equal to zero falls back to the default. Earlier
releases capped the AI Overview and the server-info
analysis at 512 tokens and ignored the configured
value on both paths.
A reasoning model counts its internal thinking tokens
against this same budget. A budget that suits a
conventional model can therefore leave no room for the
answer itself. The model then returns a response that
contains no text, and the affected panel has nothing
to render. Raise max_tokens when a summary or an
analysis comes back empty; alternatively, select a
model that emits less reasoning.
The server reports an empty response instead of
discarding the response silently. A scoped AI Overview
request fails with an error, and the estate summary
records the failure in the server log. The
GET /api/v1/server-info/{id}/ai-analysis endpoint
returns 502 with a message that names the likely
cause.
In the following example, the llm section raises the
budget for a reasoning model that a local llama.cpp
server hosts:
llm:
provider: "openai"
model: "qwen3-8b"
openai_base_url: "http://localhost:8080/v1"
max_tokens: 8192
Request Timeout (timeout_seconds)
The timeout_seconds option sets the HTTP client
timeout, in seconds, for every request the server
makes to the configured LLM provider. The timeout
applies uniformly to Anthropic, OpenAI, Gemini, and
Ollama, including Ask Ellie chat requests. The
default value is 120 seconds; values less than or
equal to zero fall back to the default.
Increase this value when running local models on
low-resource hardware or when full-context prompts
regularly exceed the default; large prompts that
combine schema, metrics, and connection data can
take longer than 120 seconds on slow Ollama hosts.
Raising the timeout to 300 prevents context
deadline exceeded errors in these environments.
In the following example, the llm section extends
the timeout for a slow local Ollama server:
llm:
provider: "ollama"
model: "llama3:latest"
ollama_url: "http://localhost:11434"
timeout_seconds: 300
Tool Descriptions (compact_tool_descriptions)
The compact_tool_descriptions option controls
whether the server sends compact or verbose tool
descriptions to the LLM. The option accepts three
values:
auto(default) uses compact descriptions for localhost endpoints and verbose descriptions for remote APIs. Compact descriptions reduce prompt token count by approximately fifty-four percent.truealways sends compact tool descriptions.falsealways sends verbose tool descriptions.
This setting affects the chat proxy (Ask Ellie) only. MCP protocol clients always receive full tool descriptions regardless of this setting.
In the following example, the llm section configures
verbose tool descriptions:
llm:
provider: "anthropic"
model: "claude-sonnet-5"
anthropic_api_key_file: "~/.anthropic-api-key"
compact_tool_descriptions: "false"
Reasoning Effort (reasoning_effort)
The reasoning_effort option sets how much a
reasoning model thinks before it answers. The option
accepts none, minimal, low, medium, high,
xhigh, or max; the server refuses to start with
any other value. When the option is unset, the server
leaves the setting out of each request and the model
uses its own default.
The setting applies to Ask Ellie, the AI Overview, and the server-info AI database analysis. Each provider translates the level into its own request field:
- OpenAI sends the level as
reasoning_effort. - Anthropic enables adaptive thinking at the given
effort, treating
minimalaslow;noneturns thinking off. - Gemini sends the level as the thinking level,
treating
noneasminimal, andxhighandmaxashigh. - Ollama ignores the setting.
Which levels a model accepts varies by model. When a
model rejects a level, the server retries the request
without the setting. A model counts its thinking tokens against
max_tokens, so a higher effort may need a larger
output budget.
Prompt Caching (prompt_caching)
The prompt_caching option accepts auto or off;
an unset value means off. With auto, Anthropic
caches the tool list, the system prompt, and the
conversation so far, so each step of an Ask Ellie
tool loop reads the unchanged part of the prompt from
the cache instead of paying the full input rate for
the part again. OpenAI and Gemini cache prompts
automatically, so the option makes no difference for
those providers; Ollama ignores the option.
Anthropic charges more than the normal input rate to write a prompt to the cache, so leave the option off when requests rarely repeat a prompt.
Extra Request Fields (extra_body)
The extra_body option adds fields to the JSON body
of every chat request the server sends through the
openai provider. Use the option to pass a setting
that the server does not model, such as the options
of an OpenAI-compatible gateway. A field in
extra_body replaces any field of the same name that
the server builds. The Anthropic, Gemini, and Ollama
providers ignore the option.
The server refuses to start when extra_body sets
stream, which the server chooses for each request,
or contains a value that cannot be sent as JSON. The
server never logs the values in extra_body, but you
should still store a credential in an API key file
rather than in this option.
In the following example, the llm section asks a
reasoning model for low effort and passes a caching
option to an OpenAI-compatible gateway:
llm:
provider: "openai"
model: "anthropic/claude-sonnet-5"
openai_base_url: "https://gateway.example.com/v1"
reasoning_effort: "low"
extra_body:
providerOptions:
gateway:
caching: "auto"
The server reads these three options at startup only; restart the server to apply a change.
OpenAI-Compatible Local Servers
The openai provider works with any server that
implements the OpenAI-compatible API. Set
openai_base_url to point at a local inference
server. The API key is optional when using a custom
base URL.
The following local inference servers are compatible:
- Docker Model Runner uses
http://localhost:12434/engines/llama.cpp/v1as the default endpoint. - llama.cpp uses
http://localhost:8080/v1as the default endpoint. - LM Studio uses
http://localhost:1234/v1as the default endpoint. - EXO uses
http://localhost:52415/v1as the default endpoint.
In the following example, the llm section configures
a local llama.cpp server:
llm:
provider: "openai"
model: "my-local-model"
openai_base_url: "http://localhost:8080/v1"
A local server that hosts a reasoning model usually needs a larger output budget than the default. For details, see Output Token Budget.
Custom HTTP Headers (custom_headers)
The custom header options add HTTP headers to every request the server sends to the LLM provider. Use them when requests pass through an LLM gateway or proxy that needs an authentication token or a routing header. The headers apply to every AI feature the server drives, including the Ask Ellie chat proxy and the AI Overview.
The server builds the headers for a request from the following sources, in order; a later source replaces a header of the same name from an earlier one:
- The
custom_headersmap supplies headers for every provider. - The
custom_headers_filesmap names a header and the path to a file that holds its value. - The
LLM_CUSTOM_HEADERSenvironment variable supplies headers for every provider. - The
anthropic_custom_headers,openai_custom_headers,gemini_custom_headers, orollama_custom_headersmap supplies headers for the matching provider only. - The
LLM_ANTHROPIC_CUSTOM_HEADERS,LLM_OPENAI_CUSTOM_HEADERS,LLM_GEMINI_CUSTOM_HEADERS, orLLM_OLLAMA_CUSTOM_HEADERSenvironment variable supplies headers for the matching provider only.
Each environment variable holds a comma-separated list
of NAME=value pairs, such as
X-Team=dba,X-Route=primary. The first = in a pair
separates the name from the value; the server skips an
entry with no =. A header with an empty value in one
of the first three sources is ignored.
Use custom_headers_files for a secret value, such as a
gateway token, so that the secret stays out of the
configuration file. The server expands a leading ~ in
the path, removes the trailing newline from the value,
and logs a warning when the group or other users can
access the file. The Ask Ellie chat proxy reads each
file once, when the server starts, so restart the server
after replacing a file; the other AI features read the
file each time they call the provider. When a file is
missing, unreadable, or empty, the server logs an error
and sends the affected requests without any custom
headers.
In the following example, the llm section sends a
gateway token from a file with every request, and adds a
routing header to Anthropic requests:
llm:
provider: "anthropic"
model: "claude-sonnet-5"
anthropic_api_key_file: "~/.anthropic-api-key"
anthropic_base_url: "https://llm-gateway.example.com/v1"
custom_headers:
X-Team: "dba"
custom_headers_files:
X-Gateway-Token: "/etc/ai-workbench/gateway-token"
anthropic_custom_headers:
X-Route: "anthropic-primary"
Knowledgebase (knowledgebase)
The pgedge-ai-kb packages install one knowledgebase database
per embedding provider and model. On Linux these files live in
/usr/share/pgedge/pgedge-ai-kb/, and each file is named
kb-<provider>-<model>.db. The <provider> and <model> parts
match the configured embedding_provider and embedding_model
values. For the default ollama provider with the
nomic-embed-text model, the file is
kb-ollama-nomic-embed-text.db. The full default path is
therefore
/usr/share/pgedge/pgedge-ai-kb/kb-ollama-nomic-embed-text.db.
The exact location can vary by deployment method and operating
system.
The built-in database_path default still points at the legacy
/usr/share/pgedge/postgres-mcp-kb/kb.db location. Set
database_path explicitly when you use the current
pgedge-ai-kb packages, so the server reads the installed file.
The embedding_provider option accepts voyage, openai, gemini,
or ollama, and embedding_model accepts any model name the chosen
provider recognises. Google publishes gemini-embedding-001 (the
default, 3072 dimensions) and gemini-embedding-2 (also 3072
dimensions); model availability varies by Gemini API key tier, so run
ListModels to verify which embedding models a given key can access.
When Gemini provides the knowledgebase embeddings, the configured
embedding_model must match the model that the KB Builder used to
produce the knowledgebase. The KB Builder uses gemini-embedding-001;
selecting a different model produces incompatible embeddings and breaks
similarity search.
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false |
Enable knowledgebase |
database_path |
string | /usr/share/pgedge/postgres-mcp-kb/kb.db (legacy; see note above) |
SQLite knowledgebase database path |
embedding_provider |
string | ollama |
Embedding provider |
embedding_model |
string | nomic-embed-text |
Embedding model |
embedding_ollama_url |
string | http://localhost:11434 |
Ollama URL |
embedding_voyage_api_key_file |
string | Voyage API key path | |
embedding_openai_api_key_file |
string | OpenAI key path | |
embedding_gemini_api_key_file |
string | Gemini key path | |
embedding_voyage_base_url |
string | https://api.voyageai.com/v1/embeddings |
Voyage base URL |
embedding_openai_base_url |
string | https://api.openai.com/v1 |
OpenAI base URL |
embedding_gemini_base_url |
string | https://generativelanguage.googleapis.com |
Gemini base URL |
Memory (memory)
The memory section controls the chat memory feature for Ask Ellie. Chat memory allows Ellie to store and recall information across conversations.
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true |
Enable chat memory |
The memory feature requires a configured PostgreSQL
datastore connection. The server stores memories in
the datastore alongside other persistent data. When
memory is disabled, the three memory tools
(store_memory, recall_memories, delete_memory)
are unavailable even when enabled in the
builtins.tools section.
Creating system-scoped memories requires the
store_system_memory admin permission. Administrators
assign this permission to groups through the admin
panel. Users without the permission can only create
user-scoped memories.
In the following example, the memory section
disables chat memory:
memory:
enabled: false
The PGEDGE_MEMORY_ENABLED environment variable can
also control this setting; see
Environment Variables for
details.
Built-in Features (builtins)
The builtins section enables or disables individual tools and resources.
Two tools are always enabled and cannot be turned off
through the builtins.tools section. The test_query
tool validates SQL without executing the query, and
the server asks Ellie to check every statement through
that tool before presenting the statement to a user.
The read_resource tool backs resource listing, so
resources become unreachable without the tool.
builtins:
tools:
query_database: true
get_schema_info: true
similarity_search: true
execute_explain: true
count_rows: true
list_probes: true
describe_probe: true
query_metrics: true
list_connections: true
get_alert_history: true
get_alert_rules: true
get_metric_baselines: true
get_blackouts: true
get_timeline_events: true
query_datastore: true
describe_datastore: true
generate_embedding: true
search_knowledgebase: true
store_memory: true
recall_memories: true
delete_memory: true
resources:
system_info: true
connection_info: true
Datastore Query Tools
The query_datastore tool runs structured queries against the datastore, and
the describe_datastore tool lists the sources that query_datastore can
read and describes their columns. Both tools default to true. The
query_datastore tool does not accept SQL, and the tool limits
connection-specific rows to the connections the caller can access, whilst
estate-wide configuration rows remain readable; the
MCP Tools and Resources
page describes the tool's parameters.
In the following example, the configuration disables both datastore query tools:
builtins:
tools:
query_datastore: false
describe_datastore: false
Memory Tools
The memory tools (store_memory, recall_memories,
delete_memory) allow Ellie to store and recall
information across conversations. The server stores
memories in the PostgreSQL datastore. When embedding
generation is enabled, the recall_memories tool
uses semantic similarity for searching. The tool
falls back to text matching when embeddings are
unavailable.
Set any memory tool to false in the builtins.tools
section to disable the tool.
In the following example, the configuration disables
the store_memory and delete_memory tools while
keeping recall_memories enabled:
builtins:
tools:
store_memory: false
delete_memory: false
recall_memories: true
Paths and Directories
| Option | Type | Default | Description |
|---|---|---|---|
secret_file |
string | /etc/pgedge/ai-dba-server.secret |
Encryption secret path |
custom_definitions_path |
string | Custom prompts file path | |
data_dir |
string | ./data/ |
Auth and conversation data |
trace_file |
string | MCP trace file path |
Data Directory
The data directory stores persistent data files:
auth.dbstores authentication data in SQLite.conversations.dbstores chat history in SQLite.
The default location is ./data/ relative to the
server binary.
In the following example, the -data-dir flag
specifies a custom location:
./ai-dba-server -data-dir /var/lib/ai-workbench/data
The data directory can also be set in the configuration file:
data_dir: "/var/lib/ai-workbench/data"
MCP Tracing
The server can log all MCP requests and responses to a trace file for debugging purposes.
In the following example, the -trace-file flag
enables tracing:
./ai-dba-server \
-trace-file /var/log/ai-workbench/mcp-trace.log
The trace file can also be set in the configuration file:
trace_file: "/var/log/ai-workbench/mcp-trace.log"
Configuration Examples
Development Configuration
http:
address: ":8080"
tls:
enabled: false
auth:
local:
enabled: true
connection_security:
allow_internal_networks: true
database:
host: "localhost"
port: 5432
database: "ai_workbench"
user: "postgres"
sslmode: "disable"
embedding:
enabled: true
provider: "ollama"
model: "nomic-embed-text"
llm:
provider: "ollama"
model: "llama3:latest"
Production Configuration
http:
address: ":8443"
tls:
enabled: true
cert_file: "/etc/ai-workbench/certs/cert.pem"
key_file: "/etc/ai-workbench/certs/key.pem"
trusted_proxies:
- "10.0.0.0/8"
- "172.16.0.0/12"
cors_origin: "https://workbench.example.com"
auth:
local:
enabled: true
max_failed_attempts_before_lockout: 5
max_user_token_days: 90
connection_security:
allow_internal_networks: false
allowed_hosts:
- "db.internal.example.com"
blocked_hosts:
- "169.254.169.254"
database:
host: "db.internal.example.com"
port: 5432
database: "ai_workbench_prod"
user: "ai_workbench"
sslmode: "verify-full"
pool_max_conns: 20
embedding:
enabled: true
provider: "voyage"
model: "voyage-3"
voyage_api_key_file: "/etc/ai-workbench/voyage-key"
llm:
provider: "anthropic"
model: "claude-sonnet-5"
anthropic_api_key_file: "/etc/ai-workbench/ant-key"
secret_file: "/etc/ai-workbench/server.secret"
data_dir: "/var/lib/ai-workbench/data"
Environment Variables
The server reads the following environment variables at startup.
PGEDGE_POSTGRES_CONNECTION_STRING
The PGEDGE_POSTGRES_CONNECTION_STRING variable
provides a PostgreSQL connection string for the
datastore. The server uses this variable as a fallback
when the configuration file does not specify database
settings.
The server applies connection settings in the following priority order:
- Database configuration from the YAML file or command-line flags.
- The
PGEDGE_POSTGRES_CONNECTION_STRINGvariable. - The default value
postgres://localhost/postgres?sslmode=disable.
In the following example, the variable specifies a remote database:
export PGEDGE_POSTGRES_CONNECTION_STRING=\
"postgres://user:pass@db.example.com:5432/\
ai_workbench?sslmode=require"
PGEDGE_DB_LOG_LEVEL
The PGEDGE_DB_LOG_LEVEL variable controls the
verbosity of database operation logging. The server
writes database log messages to stderr with a
[DATABASE] prefix.
The following values are supported:
nonedisables all database logging (default).infologs connections, queries, and errors.debuglogs metadata, pool details, and queries.tracelogs full queries, row counts, and timings.
An empty or unrecognized value defaults to none.
In the following example, the variable enables debug logging:
export PGEDGE_DB_LOG_LEVEL=debug
PGEDGE_MEMORY_ENABLED
The PGEDGE_MEMORY_ENABLED variable controls the
chat memory feature for Ask Ellie. The server reads
this variable at startup and applies the value as an
override to the memory.enabled configuration
option.
The following values are supported:
trueenables chat memory (default).falsedisables chat memory.
In the following example, the variable disables chat memory:
export PGEDGE_MEMORY_ENABLED=false
PGEDGE_AUDIT_RETENTION_DAYS
The PGEDGE_AUDIT_RETENTION_DAYS variable controls
how many days of RBAC audit events the server keeps.
The server reads this variable at startup and applies
the value as an override to the
http.auth.audit_retention_days configuration
option. A value of 0 keeps audit events forever.
In the following example, the variable keeps a year of audit events:
export PGEDGE_AUDIT_RETENTION_DAYS=365
Configuration Reload
The server supports runtime configuration reload via
SIGHUP:
kill -SIGHUP $(pgrep ai-dba-server)
A SIGHUP signal reloads the following settings:
- Database connection settings.
- LLM proxy settings.
- Knowledgebase settings.
- The federated login policy under
http.auth.oidc, as described in Single Sign-On.
A database setting given on the command line at start-up,
such as -db-host, keeps priority over the configuration
file on every reload, as it does at start-up.
The other authentication settings and the HTTP server
settings require a full restart. A reload keeps the value the
server started with and warns about each of the
settings whose change it detects, among them
http.auth.max_failed_attempts_before_lockout, which
the authentication store reads once at start-up, so
account lockout stays as configured at the last
restart until the server is restarted again.