# elelem-server

> Serves a chat page and runs an elelem session behind it, so you can drive the agent from a browser or a phone. It has no authentication and listens on every network interface.

Maturity: alpha. Install: `gem install elelem-server`. Source: https://src.mokhan.ca/elelem/server/


`elelem-server` runs one elelem session inside a small web server and
serves a chat page for it. Type a message in the browser and the agent
runs on the machine where the server runs, with that machine's files and
tools. Use it to watch or steer an agent from another device on a network
you control.

> **Warning:** The server binds to `0.0.0.0` and has no authentication, no
> TLS, and no origin check. Anyone who can reach the port can send the
> agent instructions and answer its permission prompts. If the agent has
> a shell tool, that means running commands as you. Any web page open in
> your browser can also send messages to `http://localhost:4567/message`.
> Run it only on a machine and network you trust, and block the port from
> everything else.

## Install

```bash
gem install elelem-server
```

You also need a provider gem, for example `elelem-anthropic` or
`elelem-llama`.

## Configure

```text
Usage: elelem-server [options]
    -p, --provider NAME              Provider to use (default: stub)
        --port PORT                  Port to listen on (default: 4567)
    -h, --help                       Show this help
```

The address is fixed at `0.0.0.0`; there is no flag to change it. There
is no `--model` flag; the provider's own defaults and environment
variables apply.

`elelem-server` does not load `elelem-builtins`. The session gets only the
tools and setup blocks from plugin files in `~/.agents/plugins/` and
`.agents/plugins/`. With none, the agent can talk but not act. To give it
the default tools:

```ruby
# ~/.agents/plugins/builtins.rb
require "elelem/builtins"
```

## Use

```bash
elelem-server -p anthropic --port 4567
```

```text
elelem v0.2.0 listening on http://0.0.0.0:4567
```

Open `http://localhost:4567` in a browser. Enter sends a message;
Shift+Enter adds a line. Replies and the model's thinking stream in as
they arrive. When a tool asks for permission, for example through
`elelem-tools` permissions, the page shows the question with Allow and
Deny buttons. Ctrl+C in the terminal stops the server.

## How it works

The page is one HTML file with inline CSS and JavaScript and no external
assets. The server is WEBrick with 4 routes:

| Route | Method | Purpose |
|---|---|---|
| `/` | GET | the chat page |
| `/events` | GET | server-sent events: `content`, `thinking`, `prompt`, `done` |
| `/message` | POST | `{"text": "..."}` starts a turn |
| `/answer` | POST | `{"id": 1, "text": "y"}` answers a prompt |

The session's input and output are a `WebTerminal` object. Output is
stripped of ANSI colour codes and broadcast to every connected browser.
When a tool calls `ask`, the question goes out as a `prompt` event with an
id, and the tool waits until `/answer` arrives with that id.

Each `/message` starts the turn in a new thread and returns `204`
immediately. When the turn ends, the server sends `done`.

## Limitations

- No authentication, no TLS, and a fixed `0.0.0.0` bind. See the warning
  above.
- One session for everyone. Every browser tab shares the same
  conversation and sees the same stream.
- Messages go straight to the model. Slash commands such as `/reload` are
  not interpreted.
- Nothing stops 2 turns from running at once if you send a second message
  before the first finishes.
- A page opened mid-session sees only new events, not the history.
- The page's formatting is rudimentary: line breaks in replies are not
  preserved.

## Development

```bash
git clone https://git.mokhan.ca/elelem/server.git
cd server
bin/setup
bin/test
bin/run
```

`bin/run` starts `exe/elelem-server` through Bundler and passes its
arguments on. The development Gemfile has no provider gems, so it runs
the `stub` provider unless you add one.


## Environment

| Variable | Default | Description |
|---|---|---|
| `ELELEM_PROVIDER` | `stub` | Provider to use when -p is not given. |

Canonical: https://elelem.sh/plugins/server/

