Athenode

Configuration of Athenode Pro

An Athenode Pro server takes its settings from command-line flags, environment variables and the config.json in its data folder, and serves your team through a reverse proxy that terminates TLS. Athenode Pro is the Athenode server a team runs itself, with accounts, project roles and a licence. Install Athenode Pro covers installing the package, the database and running the server under a supervisor.

Where Athenode Pro takes its settings from

Each setting is taken from the first source that sets it: a command-line flag of athenode-pro start, then an environment variable, then config.json in the data folder, then the default. --public-url wins over ATHENODE_PUBLIC_URL, which wins over publicUrl in the server section of config.json.

Pro reads its settings when it starts, so restart the server after you change a variable or config.json. A value that is missing or wrong stops the start with a message that begins "Athenode Pro cannot start:" and names the setting. athenode-pro doctor checks the same settings without starting the server and prints the public URL, the listen address and the ports it resolved.

A supervisor such as systemd passes Pro the variables of its unit or of an environment file, not those of your terminal. Set the variables there, or put the settings in config.json, as the systemd example of Install Athenode Pro does. Run doctor and the license commands with the same variables as the server, because they read the same database.

Settings of the server

Setting Flag Variable config.json Default
Public URL (required) --public-url ATHENODE_PUBLIC_URL server.publicUrl None: the start stops
Listen address --host ATHENODE_HOST server.host 0.0.0.0
Port --port ATHENODE_PORT port 3717
Service port --service-port ATHENODE_SERVICE_PORT server.servicePort The port plus 1
Trusted proxies --trusted-proxy, repeatable ATHENODE_TRUSTED_PROXIES, comma-separated server.trustedProxies, a list None
Database (required) None ATHENODE_DATABASE_URL server.databaseUrl None: the start stops
Modules None ATHENODE_MODULES, comma-separated server.modules, a list Every module of the licence
Data folder --data-dir ATHENODE_PRO_HOME None ~/.athenode-pro
Mandatory two-factor sign-in, initial value None ATHENODE_REQUIRE_2FA, 0 or 1 auth.require2fa 0
Output characters in forwarded audit entries, initial value None ATHENODE_AUDIT_FORWARD_EXCERPT_CHARS, 0 to 65536 auditForwardExcerptChars 1024
Organisation console None ATHENODE_CONSOLE_URL server.consoleUrl https://platform.athenode.com
Gateway webhook for service alerts, initial value None None serviceCheckWebhookUrl None
Signing secret of the gateway webhook, initial value None None serviceCheckWebhookSecret None
  • Public URL. The address your team opens, such as https://athenode.example.com. It must use https and have no path, query or credentials. Every request to Pro must address this host, and a request from a browser must come from this origin, or Pro refuses it. The redirect address of single sign-on, the links in webhook calls and the snippets of athenode-pro mcp-config are built from it.
  • Listen address. An IP address. 0.0.0.0 accepts connections on every interface. Use 127.0.0.1 when the reverse proxy runs on the same machine, so that the port is not reachable from outside.
  • Port. The port of the web UI, the Athenode MCP server and the API, from 1 to 65535. The reverse proxy forwards to it.
  • Service port. A second port that listens on 127.0.0.1 only, for athenode-pro status and athenode-pro stop. It must differ from the port. Do not forward it through the reverse proxy.
  • Trusted proxies. The IP addresses or CIDR subnets of your reverse proxies, such as 10.0.0.2 or 10.0.0.0/8. Pro takes the original host and the client's address from the forwarding headers of these peers only, and removes those headers from every other request. The client's address counts for the sign-in lockout per address and the limit on new MCP clients per address, so a proxy that is not listed makes every person appear to come from the proxy.
  • Database. A postgres:// or postgresql:// address with the role and its password. One Pro server runs per database. Install Athenode Pro lists the rights the role needs.
  • Modules. The modules to turn on, from gateway, plugins and specs. A module that the licence lists and that you leave out is turned off, as the Pro licence describes. An id that is not a module of Pro stops the start.
  • Data folder. Holds config.json, the master key master.key, the server's lock and logs/athenode.log. The daemon's ATHENODE_DATA_DIR has no effect on Pro.
  • Organisation console. The address of the organisations in your Athenode account, where a billing administrator changes the organisation's tier. The Open the organisation console link of a locked feature leads there, as Pro tiers describes. It must use https.
  • Gateway webhook for service alerts. serviceCheckWebhookUrl, an http or https URL, and serviceCheckWebhookSecret, up to 1,024 characters, go at the top level of config.json. Pro stores them at start while no gateway webhook is stored and the licence includes health webhooks, a Pro Team and up feature. Afterwards the value saved in the web UI applies, as Services and health checks describes. The secret stays readable in config.json, so keep the file private or set the secret in the web UI.
  • Mandatory two-factor sign-in and output characters in forwarded audit entries are initial values. Pro stores them at its first start, and an administrator changes them afterwards in the web UI: two-factor sign-in in the Security section of the Settings page, as Users and sign-in describes, and the output characters as Audit export and forwarding describes. An output value of 0 sends no output.

Other environment variables

Variable What it sets
ATHENODE_MASTER_KEY The master key itself, base64-encoded. It wins over every other source of the key.
ATHENODE_MASTER_KEY_FILE The file that holds the master key, in place of master.key in the data folder.
ATHENODE_LICENSE_TOKEN The licence token that athenode-pro license activate reads. The server also activates the licence from it at start while no stored licence works, as the Pro licence describes.
ATHENODE_LICENSE_KEY_FILE The path of a signed licence key that the server imports at start while no stored licence works, on a server without internet access, as the Pro licence describes. Set it or ATHENODE_LICENSE_TOKEN, never both.
ATHENODE_ADMIN_EMAIL The email of the first administrator, whom the server creates at start while it has none, as Install Athenode Pro describes.
ATHENODE_ADMIN_PASSWORD The initial password of that administrator, set together with ATHENODE_ADMIN_EMAIL.
HTTPS_PROXY, HTTP_PROXY, NO_PROXY The proxy for the server's requests to the internet: licence renewal, the new-version check, the plugin library and imports.
ATHENODE_CLOUD_FETCH_TIMEOUT_MS How long a new project waits for the standard plugin from the plugin library, in milliseconds, 5000 by default. See isolated networks.
ATHENODE_NO_UPDATE_CHECK With the value 1, turns off the check for a new version, which otherwise runs at start and once a day.
ATHENODE_EMBEDDINGS_URL, ATHENODE_EMBEDDINGS_MODEL, ATHENODE_EMBEDDINGS_DIMENSION, ATHENODE_EMBEDDINGS_API_KEY The embeddings service of search by meaning.

The master key encrypts the secrets Pro stores, such as SSH credentials, the single sign-on client secret and the licence token. Install Athenode Pro describes backing it up, and the master key of the daemon works in the same way.

Pro also reads the keys and variables of the daemon's configuration other than its data folder: the timeout of the plugin library, the GitHub and GitLab tokens for imports, the switches of the SSH gateway's background work and the initial values of the SSH gateway settings. Configuration of the athenode daemon lists them.

Configuration file of Athenode Pro

config.json in the data folder, ~/.athenode-pro/config.json by default, holds one JSON object. The server settings go in its server section, the port and the daemon's keys at the top level, and search by meaning under search.embeddings.

{
  "port": 3717,
  "server": {
    "publicUrl": "https://athenode.example.com",
    "host": "127.0.0.1",
    "trustedProxies": ["127.0.0.1"],
    "modules": ["gateway", "plugins", "specs"]
  },
  "search": {
    "embeddings": { "url": "http://embeddings.internal:8080" }
  }
}

A key in the server section that Pro does not know stops the start with a message that names it. A top-level key Pro does not know is reported with a warning and ignored. server.databaseUrl holds the database password, so set the database in ATHENODE_DATABASE_URL when config.json is readable by anyone but the user that runs Pro.

Commands of athenode-pro

Command What it does Options
start Starts the server in the foreground. It is also what athenode-pro with no command does. --public-url, --host, --port, --service-port, --trusted-proxy, --data-dir, --open
status Prints the running server's address and process. Exits with 0 while the server runs and 3 when it does not. --port, --data-dir
stop Stops the running server. --port, --data-dir
doctor Checks Node.js, the configuration, the data folder, the database, pg_trgm, pgvector, whether the database matches this version, the licence and the running server. Exits with 1 when a check fails. --port, --data-dir
mcp-config Prints the snippets that add the Athenode MCP server to each AI tool, as Connect to Athenode Pro describes. --client, --project, --public-url
license activate, license import, license status Activate, import and show the licence, as the Pro licence describes. --token-file, --file, --data-dir
recover Resets the password, and with --reset-2fa the two-factor sign-in, of a built-in account, as Users and sign-in describes. --email (required), --reset-2fa
help, version Print the commands and the version. None

Run every command as the user that runs the server, with the same environment, because each one reads the data folder and the database.

Put Athenode Pro behind a reverse proxy

Pro serves plain HTTP on its port. A reverse proxy in front of it terminates TLS for the public URL, forwards every path to Pro and meets these requirements:

  • Pass the original Host header, or set X-Forwarded-Host to it, and pass the browser's Origin header unchanged.
  • Run on an address you list in the trusted proxies.
  • Forward responses as they arrive, without buffering them, and allow long reads, because a call of the Athenode MCP server can wait for minutes, for example for an approval in the SSH gateway.
  • Pass the WebSocket upgrade on /api/realtime, with a read timeout above 20 seconds, such as 60 seconds. The web UI keeps one such connection per tab for its live updates.
  • Accept request bodies on /api/gateway/transfers/ at least as large as the File transfer size limit of the SSH gateway, 1 GiB by default, stream them without buffering, and pass the X-Athenode-Transfer header through. These are the one-time transfer URLs of file transfers.
  • Never forward the service port.

When the reverse proxy runs on the same machine, start Pro on the loopback address and trust that address:

athenode-pro start --public-url https://athenode.example.com --host 127.0.0.1 --trusted-proxy 127.0.0.1

Caddy

Caddy passes the headers and the WebSocket upgrade and streams request bodies without further settings. flush_interval -1 turns off the buffering of responses:

athenode.example.com {
  reverse_proxy 127.0.0.1:3717 {
    flush_interval -1
  }
}

If your site limits request bodies with request_body, set its max_size to at least the File transfer size limit of the SSH gateway.

nginx

nginx needs a location for the live updates and one for the transfers next to the main one. Replace the certificate paths and the server name with yours:

server {
  listen 443 ssl;
  server_name athenode.example.com;
  ssl_certificate     /etc/ssl/certs/athenode.example.com.pem;
  ssl_certificate_key /etc/ssl/private/athenode.example.com.key;

  location / {
    proxy_pass http://127.0.0.1:3717;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_buffering off;
    proxy_read_timeout 900s;
    client_max_body_size 512m;
  }

  location /api/realtime {
    proxy_pass http://127.0.0.1:3717;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_read_timeout 60s;
  }

  location /api/gateway/transfers/ {
    proxy_pass http://127.0.0.1:3717;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 1g;
    proxy_request_buffering off;
    proxy_buffering off;
    proxy_read_timeout 600s;
  }
}

nginx passes the Origin and X-Athenode-Transfer headers as they come. client_max_body_size in the main location lets an import of a project archive through, which can be up to 512 MiB; nginx's own default refuses bodies over 1 MB, which also stops imports of zip files and uploads of skill files. The transfers location takes files up to 1 GiB: when an administrator raises the File transfer size limit on the Settings page, raise its client_max_body_size to match.

Run Athenode Pro in an isolated network

Pro works without internet access, except for the plugin library and the Imports page. In a network without internet access:

  1. Import the licence key by hand, with a key a billing administrator downloads from your Athenode account, as the Pro licence describes. Import a new key before the current one expires.
  2. Set ATHENODE_CLOUD_FETCH_TIMEOUT_MS=300, or "library": { "fetchTimeoutMs": 300 } in config.json. A new project first asks the plugin library for the standard plugin and waits up to 5 seconds by default before it takes the copy of the standard plugin that comes with Pro.
  3. Set ATHENODE_NO_UPDATE_CHECK=1, because the check for a new version cannot reach the internet.

New projects get the standard Athenode plugin from the copy that comes with the installed version of Pro. When your network reaches the internet through a proxy, set HTTPS_PROXY instead, and the licence renews by itself through the proxy.

Turn on search by meaning

Search by meaning lets the specification search also find specifications that describe the same thing in other words. You turn it on by connecting an embeddings service that offers the OpenAI-compatible embeddings API. Pro sends it the text of the specifications and of each search. Search in the specification tree describes the search itself.

  1. Run an embeddings service that Pro can reach, or choose a hosted one.

  2. As a PostgreSQL superuser, create the pgvector extension in Pro's database once, unless Pro's role may create it:

    CREATE EXTENSION vector;
  3. Set the service's address in ATHENODE_EMBEDDINGS_URL or in search.embeddings.url of config.json.

  4. Restart Pro.

  5. Run athenode-pro doctor and check that its pgvector line says the extension is installed.

Setting Variable config.json Default
Address of the service, without /v1/embeddings, which Pro adds ATHENODE_EMBEDDINGS_URL search.embeddings.url None: search by meaning is off
Model ATHENODE_EMBEDDINGS_MODEL search.embeddings.model Alibaba-NLP/gte-modernbert-base
Dimension of the model's vectors ATHENODE_EMBEDDINGS_DIMENSION search.embeddings.dimension 768
API key of a hosted service, sent as a bearer token ATHENODE_EMBEDDINGS_API_KEY search.embeddings.apiKey None

The address turns the feature on. Set the model and the dimension to those of the model your service runs. After you change either of them, Pro indexes the specifications again for the new model. Without an address, Pro sends nothing to any service and needs no pgvector.