Shappy Backend
Shappy Backend is the control plane for all the chats that you run. It keeps the model settings, the app tools and the access settings of each connected app. It runs each conversation in celld. Clients are the embedded chats in your apps and the Chrome extension.
Note: To run the backend with Docker, follow Self-host. This page describes the parts of the backend and how to run it from the source checkout.
How a request travels
- The chat in your page sends the message to your own server.
- Your server forwards
/shappy/*to the backend with the app credential. The browser never holds the credential. - The backend checks the origin, the conversation scope of the app and the tools that the app may use.
- A celld cell runs the turn. It asks the backend for the model key at each model request.
- The model answers. MCP tool calls go to the tools that you connected.
- Text, tool results and status stream back to the page as server-sent events.
- The conversation stays in celld.
Start the backend
Requirements: Node.js 22.19 or newer, the installed dependencies of the checkout, and Docker. The backend keeps conversations in celld, which runs in Docker.
./app.sh build
./app.sh celld
./app.sh start
./app.sh celld makes the service tokens, writes them to celld.json in the data folder and to the cell project, and starts celld 0.6.1 on http://127.0.0.1:4610. Run it again after you change SHAPPYCHAT_PORT. ./app.sh start stops with a message if celld is not prepared.
The backend listens on http://127.0.0.1:8849. To use another port, set SHAPPYCHAT_PORT.
Sign in as the operator
When the backend starts, it opens a private, single-use operator link in your browser. The link signs you in to the backend pages.
- To get a new link, run
shappy loginon the same machine. In Docker:docker compose exec backend shappy login. From the source checkout:node server-dist/cli.js login. - If the browser does not open, open the URL in the
launch-urlfile in the backend data folder. - The link expires after 10 minutes.
- An operator session lasts 12 hours. It ends when you sign out or restart the backend.
Backend pages
| Page | Use it to |
|---|---|
| Setup | Follow the seven setup steps. A new installation opens here until setup is complete. |
| Playground | Chat as the operator with every connected tool |
| History | Read the Playground conversations and, under All apps, the conversations of every connected app |
| Models | Set the model endpoint and choose models |
| Connected apps | Add an app or the extension, set its origin and tools, copy or revoke its credential |
| Tools / MCP | Add and refresh MCP connections |
| Storage | See what the data folder holds |
| Operator access | See the operator session and sign out |
| Preferences | Other backend settings |
Setup steps
- Check this server: celld and storage.
- Model: where answers come from. Presets for LM Studio, Ollama and other endpoints.
- Tools: turn on the MCP connections that you added under Tools / MCP.
- Connect an app: the credential and the allowed origin.
- Test message: a message through the whole path.
- Add to your app: the code, or a prompt for your coding agent. See Set up with your agent.
- Ready: a summary.
Warning: Keep the
launch-urlfile private. Anyone with the link can operate the backend.
Configure a model
Open Models and set the inference endpoint. The backend works with servers that supply an OpenAI-compatible API, for example a local LM Studio server at http://127.0.0.1:1234/v1.
The backend finds the available models. It does not show embedding models. Each conversation keeps its model until you select a different one.
Connect app tools
Open Tools / MCP and add the MCP URL and key of your app. For local processes, use a configuration file. See App tools (MCP).
Add a client
Each app and each Chrome extension that uses the backend needs its own credential.
- Open Connected apps.
- Add a client. Enter its exact origin, for example
https://app.example.comorchrome-extension://<extension-id>. - Select the MCP connections that the client can use.
- If the client must act on its pages, grant host UI permission.
- Copy the credential. The backend shows it one time only. It stores only a hash of the credential.
Other clients and the Playground cannot see the conversations of a client. To remove access, revoke the client. Revoking also cancels its running replies.
Allow your app origin
The backend accepts browser requests only from origins that you allow. Set the list in the environment or in the configuration file:
SHAPPYCHAT_ALLOWED_ORIGINS=https://app.example.com,https://admin.example.com ./app.sh start
{
"allowedOrigins": ["https://app.example.com"]
}
Requests also need a valid credential.
Conversations API
All requests need the app credential as a bearer token.
| Request | Result |
|---|---|
POST /api/conversations with {} |
Creates a conversation. The response contains conversationId. |
GET /api/conversations |
Lists the conversations of the client |
GET /api/conversations/<id>/events |
Server-sent events: the conversation state at connect, then each change. The event ID is the state revision. Send Last-Event-ID to receive only newer state. |
GET /api/conversations/events |
Server-sent events for the list of conversations of the client |
GET /api/models |
The models that the client can choose |
GET /sdk/shappychat.tgz |
The SDK package file. No credential is needed. |
The account and workspace scope comes from the trusted configuration. It does not come from the request body.
Configuration reference
| Variable | Description |
|---|---|
SHAPPYCHAT_PORT |
The port. Default 8849. |
SHAPPYCHAT_HOST |
The listen address. Default 127.0.0.1. |
SHAPPYCHAT_PUBLIC_URL |
The address that users reach, for example https://chat.example.com |
SHAPPYCHAT_ALLOWED_HOSTS |
Extra allowed Host header values, comma-separated |
SHAPPYCHAT_DATA_DIR |
The data folder. Default: ~/Library/Application Support/ShappyChat on macOS, %APPDATA%\ShappyChat on Windows, $XDG_DATA_HOME/shappychat or ~/.local/share/shappychat on Linux |
SHAPPYCHAT_CONFIG |
Path to a JSON configuration file |
SHAPPYCHAT_ALLOWED_ORIGINS |
Comma-separated list of allowed browser origins |
SHAPPYCHAT_MODEL_URL |
The model endpoint. Default http://127.0.0.1:1234/v1. |
SHAPPYCHAT_MODEL_API_KEY |
The key for the model endpoint. Secret. |
SHAPPYCHAT_MASTER_KEY |
Base64 32-byte key that encrypts stored secrets. Default: master.key in the data folder. |
SHAPPYCHAT_SDK_TARBALL |
Path of the SDK package file that /sdk/shappychat.tgz serves |
Data folder
| File | Contents |
|---|---|
celld.json |
The celld address, service token and callback token |
launch-url |
The private operator link |
clients.json |
Client records with hashed credentials |
connections-<scope>.json |
Provider and MCP settings for one scope. Keys are encrypted. |
master.key |
The key that encrypts provider and MCP keys. Back it up. |
admin-secret |
The secret that shappy login uses to ask for a new operator link |
data-version.json |
The format of the data folder |
celld keeps the conversations and the request receipts. It has one cell for each conversation and one directory cell for each scope. It also has one ledger cell that lists the conversations of all scopes.
History shows the conversations of the Playground. Under All apps, it shows the conversations of each connected app. Both lists change immediately when a conversation changes. celld keeps its data in cells/shappy-backend/.celld in the checkout.
Warning: The backend keeps the provider keys and MCP keys that you enter in the data folder. It encrypts them with AES-256-GCM and
master.keyorSHAPPYCHAT_MASTER_KEY. Cells do not keep these keys. A cell gets the key from the backend for each model request. Make a backup ofmaster.keywith the data folder. Withoutmaster.key, the backend cannot read the keys.