Skip to content

Repository files navigation

This is a fork

Upstream: saltmd/salt.md — all of the original work is theirs, and it is excellent. This fork exists because a team needed the product under their own name on their own hardware; it is published because AGPL-3.0 requires it once you serve a modified version over a network, and because two of the fixes below belong back upstream.

What is different from upstream:

Change Why
Renamed saltdworkspace throughout (module path, env vars SALT_*DWORKSPACE_*, session cookie, API-token prefix, DB filename, webhook header, desktop URL scheme, docs) The deployment carries the team's own name
Fix: FTS5 query built without an explicit AND Any multi-word search where one word grew a stem/variant produced a silent empty result — the pattern failed to parse and the error was swallowed
Fix: FTS5 punctuation-only tokens OMS - Trade returned nothing while OMS Trade returned five pages. A lone - became a legal but empty phrase and AND-ed the whole query to zero. Pasting a document title was enough to trigger it
Fix: POST /oauth/register replied text/plain WriteHeader was called before the Content-Type was set, so Go sniffed the body. RFC 7591 requires application/json; ChatGPT rejected the registration and retried forever, never reaching the consent step
Feature: @-mentions of people, with an inbox and a notification that scrolls to the exact block Upstream's @ only linked pages
Both search paths now log their errors All three bugs above shipped precisely because a malformed query is indistinguishable from "nothing found"

The three fixes are not team-specific and are offered upstream.

dworkspace

The open-source workspace for people and AI agents.
Docs, databases and realtime collaboration for your team. An MCP server sits in the same binary, so an agent works in that workspace instead of talking about it.

Website · Documentation · Quickstart · Agents · Live demo

An agent creates a page and a database; the workspace updates while a person watches.


An agent asks to organise the launch notes. A page appears, a database is created, the rows fill in. A person opens the same board a second later and carries on editing. Same pages, same permissions, same history.

That is the whole idea. Everything below is how it works.

Quickstart

curl -fsSL https://raw.githubusercontent.com/saltmd/salt.md/main/install.sh | sh

No curl on the machine? A minimal server image often has wget instead, and the script itself is happy with either:

wget -qO- https://raw.githubusercontent.com/saltmd/salt.md/main/install.sh | sh

That one command downloads the binary for your platform, installs it and starts it, then prints the address to open. On a server it prints that machine's address rather than localhost, which is the thing most install scripts get wrong.

On a Linux server it installs a systemd service rather than leaving a process in your terminal: it starts on boot, restarts after a crash, and your shell is free. Running the same command later upgrades it. Everywhere else it runs in the foreground, which is right for trying it out on a laptop. There is nothing else to install. No database server, no cache, no object store, no separate realtime service.

Docker, if you prefer:

docker run -d -p 8420:8420 -v salt-data:/data ghcr.io/saltmd/salt.md:latest

Why dworkspace exists

Agents increasingly need somewhere to put durable, structured work. Not a chat log, not a vector store, but pages and tables a person will read tomorrow.

Today they get one of two bad options. A workspace built for humans, with an AI feature bolted to the side, which means the agent talks about the content through a chat window. Or agent infrastructure with a decent API and no interface a human being would willingly use.

dworkspace is one workspace with two front doors. A block editor, databases and realtime editing for people. An MCP endpoint for agents, on the same objects and the same permission model. And you run the whole thing yourself.

What an agent can do

Connect any MCP client to /mcp and it gets 33 tools over the same workspace you use:

  • Read and write pages: create, update, move, duplicate, trash, restore
  • Work with databases: create one, change its schema, add and query rows, configure views
  • Search the whole workspace, with the same permission checks a person gets
  • Import from a URL or a Notion export, in bulk
  • Comment, and write to a page's append-only note trail
  • Announce what it is working on, which shows live in the interface beside the page, so you can see an agent is mid-edit before you start typing

And a bounded set it cannot touch. An agent may not create or delete accounts, change two-factor settings, issue API tokens, take or restore a backup, alter instance settings, or change who is in a workspace. That list is not a promise in a README. The server sends it to every agent that connects.

Full reference: MCP tools.

Agents get permissions, not a master key

A credential belongs to a person and carries that person's access, never more. Beyond that:

  • Every workspace decides for itself what agents may do there: anything they were granted, only signed-in connections, or nothing at all.
  • Tokens narrow by scope and by workspace.
  • Agent actions are attributable: the activity log distinguishes them from yours.
  • Administration is deliberately out of reach of any token.

Giving an agent write access is only useful if you can still say who reached what, and what changed. See Permissions.

And it is a real workspace

Not developer infrastructure with a login screen.

Write. A block editor with a slash menu, nested lists, checklists, quotes, code, tables, images and callouts. Page links, backlinks, tags, covers and icons. Comments in a side panel.

Organise. Turn any page into a collection with typed properties: text, number, select, multi-select, date, person, checkbox, checklist, URL, relation, rollup, formula and backrelation. Look at it as a table, board, list, gallery, calendar, timeline or form. Filter, sort, group.

Together. Realtime editing with live cursors, comments, page history and an activity log. Share a page publicly with an optional password and expiry.

Full-text search covers page text and the contents of uploaded PDFs, with German stemming so Verträge finds Vertrag.

Architecture

   Claude · ChatGPT · Cursor · any MCP client
                     │
                    MCP
                     │
              ┌─────────────┐
   people ──▶ │   dworkspace   │ ◀── REST API
    (browser) └─────────────┘     webhooks · ICS
                     │
            SQLite file + uploads

One Go process. CGO_ENABLED=0, so the binary is static and the SQLite driver is pure Go. The frontend is embedded in it. Backing up is copying one file and one directory.

No PostgreSQL, no Redis, no object store, no separate collaboration server.

Self-hosting

Install one binary, install.sh, or the Docker image
Data one SQLite file plus an uploads directory
Update swap the binary or pull the image, restart
Backup stop, copy two paths, start
Platforms Linux, macOS and Windows, amd64 and arm64

A desktop application for macOS is available too. It is a window onto a server you run, not a second copy of the product. See The desktop app.

Documentation

dworkspace/wiki has 40 pages covering every screen, every property type, every tool an agent can call and every setting on the server.

It is derived from this source and checked against it on every build. A tool name that stopped existing, an API path that is not a route, a screenshot whose component has changed: each one fails the build. Every page is also available as plain Markdown at the same address with .md on the end, and /wiki/llms.txt indexes them for agents.

Contributing

Issues and pull requests are welcome. Pull requests need a signed CLA. CONTRIBUTING.md says what that means and why it exists.

Security reports: dev@dworkspace, not a public issue. See SECURITY.md.

License

The components dworkspace is built on, and their licences in full: THIRD-PARTY-NOTICES.md. A running instance serves the same list at /licenses.

AGPL-3.0. Use it, run it at work, change it. If you offer it to others over a network, publish your changes.

About

Fork of salt.md, renamed and with three upstream search/OAuth bugs fixed. Self-hosted workspace where any AI connects over MCP and inherits the same workspace rules.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages