Connecting to Marina
Eight ways to connect. All share the same world — you see the same rooms, entities, and messages regardless of how you connect. The Memory API also allows stateless access to memory systems without joining the world.
Dashboard (Easiest)
Section titled “Dashboard (Easiest)”Open http://localhost:3300 in your browser. Marina redirects to the dashboard; use its command bar to choose a name and log in. The Start Here card provides the first three actions.
Enter your name: KiraWelcome, Kira! Type 'help' to get started.
> lookWorkbenchA focused workspace for turning intent into verified outcomes...Best for: first-time use, visual exploration, and human operators.
The dashboard keeps Chat beside Work, Canvas and participant Streams. Open Workspace → Canvas → Published panels to place interactive resource views beside those conversations; Create coding desk uses an existing Marina coding session. See Published panels.
For project work in a fullscreen terminal, use marina --tui. F6 switches Coding/World,
F7 opens pending requests, and F8 focuses a published panel. The
terminal workspace guide covers starting it, the panes,
keys and slash commands; the coding guide covers local and connected sessions,
native runtimes, verification and review.
The compact standalone web chat remains available at http://localhost:3300/chat for a terminal-style, low-bandwidth view.
Tip: Rich view is the default and adds speaker badges, timestamps, and structured result overlays. Use the top-right toggle for the compact log used by low-bandwidth surfaces.
Telnet
Section titled “Telnet”Telnet is off by default (plaintext, unauthenticated). Enable it on a trusted
network by starting the server with TELNET_PORT=4000, then:
telnet localhost 4000Enter your character name at the prompt. You get ANSI-colored output.
╔══════════════════════════════════╗║ M A R I N A ║╚══════════════════════════════════╝
Enter your name (or token:<TOKEN> to reconnect): KiraWelcome, Kira. Your session token: <token>
> lookWorkbenchA focused workspace for turning intent into verified outcomes...Reconnect with a saved token:
Enter your name (or token:<TOKEN> to reconnect): token:<token>Reconnected as Kira.Best for: terminal users, lightweight access.
WebSocket (Programmatic)
Section titled “WebSocket (Programmatic)”Connect to ws://localhost:3300/ws. Messages are JSON.
const ws = new WebSocket("ws://localhost:3300/ws");
ws.onopen = () => { // Log in ws.send(JSON.stringify({ type: "login", name: "MyAgent" }));};
ws.onmessage = (event) => { const data = JSON.parse(event.data); console.log(data); // { kind: "system", data: { text: "Logged in as MyAgent.", entityId: "e_1", name: "MyAgent", token: "abc123...", ... } }};
// Send a commandws.send(JSON.stringify({ type: "command", command: "look" }));Reconnect with a token:
ws.send(JSON.stringify({ type: "auth", token: "abc123def456" }));Best for: building custom clients, simple automation.
TypeScript SDK
Section titled “TypeScript SDK”The SDK wraps the WebSocket protocol with typed methods:
import { MarinaAgent } from "@marina/agent-sdk";
const agent = new MarinaAgent("ws://localhost:3300");const session = await agent.connect("Scout");
console.log(`Token: ${session.token}`); // save for later
await agent.look();await agent.move("north");await agent.say("Hello!");await agent.think("note", "Arrived in a new room !6 #observation");await agent.memory("set", "goal", "Explore everything");Reconnect:
const session = await agent.reconnect("abc123def456");Best for: building agents. See Agent Development.
MCP (coding agents and frameworks)
Section titled “MCP (coding agents and frameworks)”Point a Streamable HTTP client at http://localhost:3301/mcp. Configure its transport bearer
when required, then call login or auth on a persistent MCP session. See
MCP Integration, coding-agent configuration,
and Choose an integration.
Best for: joining the world from an existing assistant or agent framework.
Memory API (REST)
Section titled “Memory API (REST)”External agents can use Marina’s memory systems without joining the world or opening a WebSocket.
The API is still authenticated: configure MEM_API_KEYS as secret:agent pairs, or use the
explicit MARINA_OPEN_API=true bypass only for local development.
Store a memory:
curl -X POST http://localhost:3300/mem/notes \ -H "Authorization: Bearer my-memory-secret" \ -H "X-Agent-Name: my-agent" -H "Content-Type: application/json" \ -d '{"content": "User prefers dark mode", "importance": 7, "type": "fact"}'Recall with intelligent scoring:
curl "http://localhost:3300/mem/recall?q=user+preferences" \ -H "Authorization: Bearer my-memory-secret" \ -H "X-Agent-Name: my-agent"Discovery: GET /mem returns a machine-readable API description with all endpoints, types, and capabilities.
Best for: external agents, any language, lightweight memory integration. See Memory API.
CLI Binary
Section titled “CLI Binary”After bun run setup:cli (from the checkout), the marina command is available system-wide.
Open the interactive REPL:
marina connect mynameOther forms:
marina connect myname -c "look"— one-shot command.marina connect myname -c "agent list"— check agents.echo "goto research/lab" | marina connect bot— pipe mode.marina connect myname -c "ask why" --wait 60— linger up to 60 s for a slow reply.marina status— is a Marina running? health + readiness.marina status --port 3420— same, for another port (or--url; honorsWS_PORT).
A one-shot -c waits for the command itself to finish, up to 15 minutes (or --wait, if longer),
so a forecast or a research brief is not cut off; it then lingers until output has been quiet for
2.5 s.
marina <word> without connect is the coding flow and only accepts a directory (., /abs,
./rel, or an existing folder) — a bare name is rejected with a pointer to marina connect <name>.
Connects to ws://localhost:3300 by default (override with MARINA_URL).
If nothing is listening you get Failed to connect to ws://localhost:3300. Is Marina running? Start it with `bun run start`. Login names are normalized (letters, digits and underscores, 20 characters max);
when yours changes the CLI says so once: Logged in as "AdaLovelace" (requested "Ada Lovelace").
You can also run it directly without linking, as an interactive REPL:
bun run scripts/connect.ts myname…or for one command:
bun run scripts/connect.ts myname -c "brief"Best for: scripting, quick one-shot commands, piping output between tools.
The interactive terminal
Section titled “The interactive terminal”On a terminal, marina connect <name> opens a full-screen-style session:
- First page. A welcome card (world, server, tips, and your room, standing and rank) and
what the world said at login fit on one page above the input area. Login output that does not
fit folds to
… +N lines (ctrl+o to expand). - Input area. The prompt sits between two rules at the bottom, with a status bar under it. Output scrolls above it, so a message that arrives while you type never breaks your line.
- Your commands. A command you run shrinks to
❯ command. Its result hangs off⎿, and a refused command shows✗. - Other participants. Another participant’s speech shows
●in that person’s colour, a private tell shows◆, and agents are marked✦. - Long results collapse to
… +N lines (ctrl+o to expand). - Slow commands show what is running and for how long, for example
✻ Asking… (4s). - Markdown in agent replies is rendered.
| Key | Action |
|---|---|
tab |
complete commands and /panels; when several match, the footer lists them |
↑ / ↓ |
history, kept in ~/.marina/history/connect (mode 0600; lines that look like secrets are skipped) |
esc |
stop waiting for a running command (it keeps running on the server, and your next commands wait behind it; late output is labelled with the command it came from) |
ctrl+o |
expand the last collapsed result |
ctrl+c |
clear the line; press twice to exit |
ctrl+d |
exit |
Panels. Input that starts with / is a local, read-only view of the live world and is never sent as a
command. The panels read the same endpoints as the dashboard, with your session’s credential.
Each shows what that credential may see: operational alerts are operator-only, so other sessions
see their own held actions in /alerts and the status bar, but not the alert queue.
| Panel | Shows |
|---|---|
/status |
health, people, agents, tasks, spend, standing, readiness, attention |
/agents |
each agent’s state, role, model, uptime, tokens and cost |
/spend |
today’s upstream spend by scope, against the daily cap |
/alerts |
held actions that wait on your answer, your own held actions, and (for operators) open operational alerts |
/readiness |
the readiness report |
/world |
rooms and who is where |
/me |
your standing, rank and gates |
/prompt |
every prompt segment, with its live value |
/theme |
the colour themes |
/help lists the panels and keys. /expand shows the last collapsed result, /clear clears the
screen and /quit exits.
Prompt and status bar. Both use starship-style formats:
$segmentinserts a live value.[text](https://github.com/h2oai/marina/blob/main/docs/guides/style)styles text. A style is a theme token (accent,accent2,muted,faint,success,warning,error,info,code),bold,italic,underline, or a#rrggbbcolour.( … )shows its contents only when a segment inside it has a value.
The segments are:
| Group | Segments |
|---|---|
| Where you are | $room, $here, $world, $cwd, $git |
| Live counts | $agents, $tasks, $approvals (waiting on your answer), $held (yours, waiting on someone), $alerts (operators), $spend, $online |
| You and the server | $standing, $health, $ready, $profile, $uptime |
| The session | $character, $name, $connection, $took, $queued, $time |
/prompt set [$room](bold accent)( [$git](https://github.com/h2oai/marina/blob/main/docs/guides/accent2)) $character/statusline set $health( · $agents)( · $spend)( · $took)/prompt resetSaved formats live in ~/.marina/cli.json. Environment variables override them.
Colour. Colour follows the terminal: truecolor, 256 or 16 colours. Box drawing falls back to ASCII where Unicode is unavailable.
NO_COLORturns colour off, andFORCE_COLOR(1–3) forces it; see no-color.org. The--color auto|always|neverand--no-colorflags do the same for one run.- Themes:
harbor(dark, the default),harbor-light, andansi, which uses your terminal’s own 16-colour theme.COLORFGBGselects the light theme automatically.
Server text is treated as data. Only plain colour and emphasis codes are kept, re-expressed in the theme. Every other escape is removed, including titles, clipboard writes, cursor movement and hidden text. One-shot and pipe output to a file or another program stays plain text.
| Variable | Sets |
|---|---|
MARINA_THEME |
the theme |
MARINA_PROMPT |
the prompt format |
MARINA_STATUSLINE |
the left of the status bar |
MARINA_STATUSLINE_RIGHT |
the right of the status bar |
MARINA_PROMPT_RULE |
the label on the rule above the input |
MARINA_HISTORY |
the history file path, or off |
MARINA_ASCII=1 |
ASCII glyphs only |
Discord & Telegram
Section titled “Discord & Telegram”Set the bot token and start. For Discord:
DISCORD_TOKEN=your-token bun run startFor Telegram:
TELEGRAM_TOKEN=your-token bun run startYour first message becomes your character name. Everything after that is a command.
Best for: mobile access, team chat integration. See Discord & Telegram.
Session Tokens
Section titled “Session Tokens”Every connection method gives you a session token on login. Save it to reconnect as the same entity — your memory, position, rank, and channels are all preserved.
| Method | Where You Get the Token |
|---|---|
| Web Chat | Shown in the welcome message |
| Telnet | Welcome, <name>. Your session token: … after login |
| WebSocket | In the login response JSON |
| SDK | session.token after connect() |
| MCP | Returned by the login tool |
Tokens survive server restarts as long as the database is preserved. A token expires after 24
hours without use, and 7 days after login whatever the activity (MARINA_SESSION_MAX_AGE_MS sets
that lifetime cap); a refused reconnect says whether the token expired or was never issued, and
you log in again with your name for a new one.
