Skip to content

Free software, and how to run it yourself

Soldlyne is under the GNU Affero General Public License v3.0: run it, study it, change it and share it. If you offer a modified version to others over a network, publish your changes under the same license.

What you need

  • Node 20 or later and pnpm
  • Postgres
  • An address and a secret for the install
  • To try it locally: Docker for the database
Local
docker run -d --name soldlyne-db \
  -e POSTGRES_USER=soldlyne -e POSTGRES_PASSWORD=soldlyne -e POSTGRES_DB=soldlyne \
  -p 55433:5432 postgres:17-alpine
cp .env.example .env   # then fill it in
pnpm install
pnpm db:migrate
pnpm dev --port 3100

On a server

It runs wherever Node and Postgres do. On Vercel, pnpm vercel-build applies the migrations on each deploy and vercel.json sets the region and the hourly job. Elsewhere:

pnpm install
pnpm db:migrate
pnpm build
pnpm start

Then call /api/cron/sync every hour with Authorization: Bearer <CRON_SECRET>, if you connect mailboxes. With no mailbox connected anywhere, the call stops at a cached answer without touching the database.

The settings that matter first

VariableWhat for
DATABASE_URLPostgres, as a role allowed to SET ROLE soldlyne_app.
DATABASE_URL_UNPOOLEDThe owner’s direct address, for migrations, when your host pools connections.
BETTER_AUTH_URLThis install’s public address.
BETTER_AUTH_SECRETSigns sessions and quote links.
SOLDLYNE_ADMINSWho may get an account without an invitation and start workspaces. Empty means nobody.

The full list, with mail and mailbox sync, is in the README.

The database’s roles

Migrations run with the owner’s address, and the first one creates soldlyne_app, a role with no login that can’t bypass row-level security. The app connects with an address allowed to take that role. Each operation on a workspace’s data is then a transaction that takes the role and sets the workspace, so row-level security limits it to that workspace’s rows, whatever the query says.

One thing to check: a superuser or a role with BYPASSRLS sees every row when it isn’t in that role. Some hosts give their owner role that attribute.

Signing in

Your company’s identity provider

Any OpenID Connect server. When one is set, it is the only way in, and it must vouch for each address.

Addresses and passwords

Sign-in stays closed until a mailed link proves the address, so this path needs a Resend account and a sender.

Either way, nobody gets an account until their address is on SOLDLYNE_ADMINS or has an invitation still good.

Connecting an assistant

Add your install’s /api/mcp address to Claude, ChatGPT or any MCP client as a remote connector. The client registers itself, you sign in and approve it, and it acts for you in every workspace you belong to. In Claude Code:

Claude Code
claude mcp add --transport http soldlyne <your address>/api/mcp

Contributing

Report a problem or suggest something in the issues. The README and the product document in the repository say how it’s built and what it won’t do.

Open an issue