Symphonix Documentation · Core 0.61.0

Installing the platform

Every component, in the order it has to start, with the commands — and a checklist at the end that tells you whether the installation is actually working.

For
Whoever is setting the platform up: a developer or a systems administrator.
Takes
45 minutes for the two required components; about 90 with knowledge and databases.
You end up with
A running Control Panel, a running Studio you can sign in to, and whichever of the Collection Server and SQL Connection Manager you need — all verified.
Before you start
  • Node.js 20.11 or later. Check with node -v. Read the warning about Node 24 below before you settle on a version.
  • The four project folders, side by side in one directory.
  • Docker Desktop, only if you will run agents as container images. Agents run perfectly well as folders without it.
  • A terminal, and the ability to leave two or three windows running.

What you are installing#

Five things. The first two are required; the rest are installed when you need what they do.

ComponentFolderDefault portNeeded?
Symphonix Control Panel
the board every agent reports to
LGStudioMonitor5180Required. Start it first.
Symphonix Studio
where flows are written and deployed
LGStudio5174Required for building agents.
Symphonix Core
the engine, compiler and runtime
LGFlownone — it is a library and a commandRequired. Not a server.
Collection Server
indexes documents and answers from them
LGFlow/collection7300Only for agents that answer from documents.
SQL Connection Manager
holds database connections and schemas
LGFlow/database7500Only for agents that query a database.
Why the folders are named differently from the products

The folders, packages and import names are lgflow, lgstudio and lgstudio-monitor; the products are Symphonix Core, Symphonix Studio and the Symphonix Control Panel. That is deliberate and will not change: every generated project vendors the engine under its package name and pins it, so renaming the package would break every project already on disk until it was reinstalled. Commands name folders; screens name products.

Before anything#

Node.js, and the one version question that matters#

Node 20.11 or later is the floor, declared by the packages themselves. Use Node 24 if any agent here will stop and wait for a person — a form, an ask node, or an approval.

On an older Node, a waiting agent forgets what it was waiting for

From Core 0.26.6 the waiting state is kept in node:sqlite, which arrived well after 20.11. On an older Node the agent still runs, and says Waiting: in memory when it starts — which means a restart loses whatever somebody had half-filled in. It is not an error and nothing fails; you simply lose the thing you were least expecting to lose. Read that line on startup.

Where the folders go#

Put the four project folders side by side in one directory. Several defaults depend on it: the Studio serves flows from ../LGFlow with no flag when the two are siblings, and the test and sweep scripts in each project reach into ../LGFlow/scripts.

C:\Dev\Apps\
  LGFlow\              Symphonix Core — the engine, and the collection/ and database/ servers
  LGStudio\            Symphonix Studio
  LGStudioMonitor\     Symphonix Control Panel

Any directory works; these paths are used throughout this page as an example.

Installing dependencies#

  1. on the machine Open a terminal in each of the three folders in turn and run npm install. The platform has almost no dependency tree — Core has five packages, the Studio one and the Control Panel one — so this is quick.
  2. on the machine If you will use the SQL Connection Manager, also run npm install in LGFlow/database. It has its own package.json and its own three drivers, deliberately kept out of everything else.
  3. on the machine The Collection Server lives in LGFlow/collection and needs no separate install — it runs on Core's own dependencies.
Check before going on

node -v prints 20.11 or later, and npm install finished without errors in each folder. There is no build step in any of these projects — nothing is compiled, so there is nothing else to run.

Starting the components, in order#

The order matters, and this is the reason: the Studio asks the Control Panel whether people must sign in. Start them the other way round and you get a Studio with no door.

1 · The Control Panel, first#

  1. on the machine Open a terminal in LGStudioMonitor and start it:
    cd C:\Dev\Apps\LGStudioMonitor
    node index.js --port 5180
    It stays in the foreground. Ctrl+C stops it. npm start does the same thing on the default port.
  2. on the machine Watch the console for Runner registered. Starting the board also starts a runner for this machine, which is what later lets the board stop and start agents on it.
  3. in the Control Panel Open http://127.0.0.1:5180 in a browser. You should get the Control Panel.
Binding wider than loopback, and the token that goes with it

By default the board listens on 127.0.0.1 only. If an agent will run inside a container it cannot reach that — inside a container 127.0.0.1 is the container's own loopback — so the board has to be bound wider with --host 0.0.0.0. It refuses to do that without a token, and says so:

Listening beyond 127.0.0.1 without a token would let anyone who can reach the port terminate your agents. Set MONITOR_TOKEN.

Put MONITOR_TOKEN in that folder's .env so the command line carries no secret, and give each agent the same value. If nothing is containerised, leave the flag off — loopback is the safer default and needs no token.

2 · The Studio, second#

  1. on the machine Open a second terminal in LGStudio and start it:
    cd C:\Dev\Apps\LGStudio
    npm start
  2. on the machine Read the one line on the console that is worth reading every time:
    sign in:   when-known, through http://127.0.0.1:5180
    That line, and not the screen, says which mode the Studio came up in.
  3. in the Studio Open http://127.0.0.1:5174.
Three steps, not two: start the board → refresh the page → sign in

The Studio asks the board whether a sign-in is required at all. The setting is STUDIO_SIGN_IN and its default is when-known, meaning ask while a board is reachable and has people in it. If the board is not answering when the page loads, the Studio opens with no door at all — and a tab that was already open before the board came up keeps showing whatever it was showing.

On any machine more than one person can reach, set STUDIO_SIGN_IN=required in the Studio's .env. That makes an unreachable board mean nobody gets in rather than everybody does.

Check before going on

The Studio's page loads at 127.0.0.1:5174, and the console line above names your board's address. If the Studio loads but shows no sign-in and you expected one, the board was not reachable when the page loaded: confirm the board is up, then refresh the page — restarting the Studio is not what fixes it.

3 · The Collection Server, if agents will answer from documents#

  1. on the machine Start it on its own port:
    cd C:\Dev\Apps\LGFlow
    node collection/collection-server.mjs --http 7300
  2. on the machine Its settings come from LGFlow/collection/.env. The names it reads are COLLECTION_PORT, COLLECTION_DB, COLLECTION_BOARD_MAY_STOP, MONITOR_URL and MONITOR_TOKEN. There is an .env.example beside it listing them.
  3. on the machine Documents live on this machine. A collection reads files from a folder on the Collection Server's own disk — not from your laptop, and not through a browser upload. Decide now which machine that is.
Why it reads COLLECTION_PORT and not PORT

Because the board's runner hands its own environment to anything it starts and takes PORT out on the way. A stray PORT on a machine would otherwise override every agent's own, which is a hard fault to find. The same reasoning gives the SQL Connection Manager DATABASE_PORT.

4 · The SQL Connection Manager, if agents will query a database#

  1. on the machine Start it from its own folder:
    cd C:\Dev\Apps\LGFlow\database
    npm start
    That script is node database-server.mjs --http 7500.
  2. on the machine Its settings are DATABASE_PORT, DATABASE_DB, MONITOR_URL and MONITOR_TOKEN, from LGFlow/database/.env.
Why this is a separate package at all

It owns the database drivers — pg, oracledb and mssql — so that the engine does not, and so that no generated agent carries them. Three drivers in one component that needs them, rather than in every agent that does not. It supports Postgres, Oracle and SQL Server. Released

When components are on different machines#

Nothing requires them to share one. Each is reached by an address, and the addresses are configured rather than assumed.

What needs to reach whatHow it is told
The Studio → the Control PanelThe Studio's own environment. The console line at startup prints the address it will use.
An agent → the Control PanelMONITOR_URL in the agent's .env, plus MONITOR_TOKEN when the board is bound beyond loopback.
An agent → the Collection ServerThe server's entry in the Control Panel's MCP catalogue, which holds its address.
The Collection Server → its documentsA folder path on the Collection Server's own machine.
Inside a container, 127.0.0.1 means the container

Anything on the host machine is host.docker.internal, and that name also resolves on Windows itself — so one value works in both places. It affects MONITOR_URL (ws://host.docker.internal:5180/agent) and PGHOST or anything else pointing at a local service. The service also has to accept the connection: Postgres needs listen_addresses set beyond loopback and a pg_hba.conf entry for the address Docker's NAT presents.

Environment variables, by name#

Each component reads its own .env from its own folder. These are the names; the values are yours.

Never put a secret anywhere but a .env file

Not on a command line, not in a flow, not in a deployment setting. The platform is built around this: a flow names an MCP server and never its credential, agents sweep secrets out of anything they report, and a generated project's Dockerfile does not copy .env — .dockerignore excludes it, and a test holds both. A folder's .env sits on one machine; an image is pushed to a registry and its layers can be read back.

WhereNameWhat it decides
Control PanelMONITOR_TOKENRequired before the board may bind beyond loopback. Agents send the same value.
ENTRA_*, LDAP_*Sign-in through Microsoft Entra or an LDAP directory. ENTRA_TENANT_ID, ENTRA_CLIENT_ID, ENTRA_CLIENT_SECRET, ENTRA_REDIRECT_URI; LDAP_URL, LDAP_BASE_DN, LDAP_BIND_DN, LDAP_BIND_PASSWORD, LDAP_ATTRIBUTE, LDAP_INSECURE. There is an .env.example in that folder listing them all.
StudioSTUDIO_SIGN_INwhen-known by default. Set to required on any shared machine.
Collection ServerCOLLECTION_PORTThe port. Not PORT — see the note above.
COLLECTION_DBWhere its index is kept.
COLLECTION_BOARD_MAY_STOPWhether the board is allowed to stop it.
SQL Connection ManagerDATABASE_PORT, DATABASE_DBIts port and its store.
Each deployed agentPORTThe port it serves its chat page on. With nothing set it asks the operating system for a free one and prints the address it got — so it is different on every start.
MONITOR_URL, MONITOR_TOKENWhich board to report to, and the token if the board requires one.
BIND, TRIGGER_BINDWhat the chat door and the webhook endpoint listen on. Both loopback by default, and neither implies the other. An agent bound wider than loopback says so on stdout.
KNOWLEDGE_<NAME>_FOLDERWhere the documents for a named collection are. There is nowhere in a flow to put this, which is deliberate.
The webhook endpoint has no Host check

The chat door checks Host and that check is not configurable. The trigger endpoint does not — whatever reaches it starts the flow. That is why TRIGGER_BIND is a separate decision from BIND rather than inheriting it, and why widening it is something to do deliberately and behind something.

The first administrator#

The Control Panel holds people, roles and privileges, and somebody has to be the first one.

  1. in the Control Panel Open the Control Panel at http://127.0.0.1:5180. On a board with no people in it, STUDIO_SIGN_IN=when-known means the Studio will not ask for a sign-in — which is convenient on a single-machine setup and is exactly what you are about to change.
  2. in the Control Panel Open Settings and add the first user and the role that may manage the estate. The privileges this page refers to elsewhere — agents.manage for the MCP catalogue, access.manage for an agent's tool subscriptions — are granted here.
  3. on the machine Once there is a person on the board, set STUDIO_SIGN_IN=required in the Studio's .env and restart the Studio.
The exact screens for adding a user and building a role are not captured here yet

This page describes where that work happens and which privileges matter; the field-by-field walkthrough of Settings → users and roles has not been written against a running Control Panel, so it is not written here as though it had. The product repository's own material covers the thirty privileges and what each grants. Planned

Starting and stopping, day to day#

WhatStartStop
Control Panelnode index.js --port 5180Ctrl+C
Studionpm startCtrl+C
Collection Servernode collection/collection-server.mjs --http 7300Ctrl+C
SQL Connection Managernpm start in database/Ctrl+C
An agent, as a foldernode run.js in the generated projectCtrl+C
An agent, as an imagedocker start <name>docker stop <name> — a graceful stop, which removes its lock. docker rm -f kills it and leaves the lock behind, and the next start waits 20 seconds for the heartbeat to go quiet before taking the folder.

The final checklist#

The installation is working when all of these are true. Each one is something you can see, not something you can assume.

  1. node -v prints 20.11 or later — and 24 or later if any agent will wait for a person.
  2. The Control Panel answers at its address, and its console said Runner registered.
  3. The Studio answers at its address, and its startup line names your board.
  4. You can sign in to the Studio — or you have deliberately decided that this machine does not require it.
  5. If you installed it: the Collection Server is running, and you know which machine its documents folder is on.
  6. If you installed it: the SQL Connection Manager is running.
  7. If agents will be containers: docker version shows a Server section, not only a Client, and MONITOR_TOKEN is set on both the board and the agents.
  8. No secret is anywhere except a .env file.
The one test that exercises all of it

Follow Build your first agent. It ends with an agent you deployed, started, talked to, and found on the board — which is every component above, proved by use rather than by inspection.

Common installation problems#

SymptomCauseWhat to do
The Studio shows no sign-inThe board was not reachable when the page loaded.Confirm the board is up, then refresh the Studio page. Restarting the Studio is not what fixes it. To make this impossible, set STUDIO_SIGN_IN=required.
The board refuses to start with a message about a token--host 0.0.0.0 without MONITOR_TOKEN.Set the token in the board's .env, or drop the flag if nothing is containerised.
An agent starts but never appears on the boardIt could not reach MONITOR_URL when it started.From a container, the address is host.docker.internal, not 127.0.0.1. Check the agent's log for the Monitor: registered line.
An agent says Waiting: in memoryNode older than 24.Upgrade Node if that agent waits for people. Otherwise it is only a note.
A collection says never built after a buildThe folder path is not readable on the Collection Server's machine.Check the path on that machine, not the one you typed it from.
An agent stands down immediatelyTwo copies of one flow — usually the Studio's Play and a container at once.Stop one. Nothing undoes a stand-down when the other copy goes away; see Deploy and monitor.
A port is already in useSomething else has it, often a previous run.Every component takes a port on the command line or from its own named variable. Nothing here insists on a particular number.
When something looks wrong, three questions in this order
  1. Is the board up? Almost everything confusing downstream — a Studio with no sign-in, an agent that answers nobody — is this.
  2. Did the agent register? Look for the Monitor: registered line in its log.
  3. Is there a second copy? Check for a container and for Play in the Studio at the same time.
Which build this describes

Core 0.61.0 · Studio 0.41.0 · Control Panel 0.53.0 · DSL 0.33 · protocol 0.19. Ports, commands and variable names on this page were read out of the repositories at build time or verified against them by hand; see the verification report that ships with this site for which is which.