Skip to content

Connect a second computer

In this tutorial you connect a laptop to your Jezero server. The laptop gets its own key, the Claude Code plugin sends its sessions to the server when they end, and you watch the first one become an item you can search from either computer.

Before you start

You need:

Each step says where it runs: on the server or on the laptop.

1. Build the client bundle (on the server)

The laptop downloads the client and the plugins from your server. Build the bundle once in the checkout:

cd ~/jezero
python3 scripts/build_clients.py

You should see:

built /home/me/jezero/dist/client, /home/me/jezero/dist/jezero-client.tar.gz and plugins/ (version 0.5.1)

The server offers the file at /client/jezero-client.tar.gz without a key: it is the same public code as the repository. See Serve the plugin bundle.

2. Get the client (on the laptop)

Download the bundle and unpack it in ~/.jezero-src:

mkdir -p ~/.jezero-src
curl -fsSL https://YOUR-JEZERO/client/jezero-client.tar.gz | tar -xz -C ~/.jezero-src
python3 ~/.jezero-src/jezero-client/jezero_client.py --version

You should see:

0.5.1

jezero_client.py is the client core: one Python file with no dependencies, shared by every plugin.

3. Create the laptop's key (on the laptop)

python3 ~/.jezero-src/jezero-client/jezero_client.py init --url https://YOUR-JEZERO --device laptop

You should see:

Device key created. The key stays in /home/me/.jezero; the server only keeps its SHA-256 fingerprint.
Ask the Jezero admin to approve it with:

  jezero device approve laptop SHA256

The key is in ~/.jezero/token, readable only by you, and the server address in ~/.jezero/client.json. The printed SHA256 is the key's fingerprint, not a secret: send the whole jezero device approve line to the server's admin, which is you.

Check the key before it is approved:

python3 ~/.jezero-src/jezero-client/jezero_client.py status

You should see:

key: /home/me/.jezero
server https://YOUR-JEZERO: HTTP 401 {"ok":false,"error":"unknown token"}
queued sessions: 0
rejected uploads: 0

The first line is the folder that holds the key. The 401 is expected: the server does not know the key yet. Sessions the laptop tries to upload before the approval wait in its queue.

Note

A computer whose sessions must not reach Jezero, such as the server itself (its connectors already read its sessions), gets a key with init ... --no-upload. The printed line then ends in --read-only, and the plugins there only search. If init says the computer is already set up, it already has a key (for example from the first tutorial): add --force to replace it.

4. Approve the laptop (on the server)

Run the line the laptop printed, with uv run in front:

cd ~/jezero
uv run jezero device approve laptop SHA256

You should see:

approved laptop; the server picks up the new key within a second (backup: /home/me/jezero/jezero.toml.bak-20261022T034500Z)

The command appended to jezero.toml a client for the laptop:

[[clients]]
# Device laptop: reads Jezero and uploads its sessions to the inbox.
name = "laptop"
token_sha256 = "SHA256"
sources = ["agent-*"]
upload = true

sources = ["agent-*"] lets the laptop read every agent source, its own included. upload = true lets it send session files to its own folder of the inbox, data/inbox/laptop/. The command also added five connectors, one per agent, that read that folder: agent-claude-code-laptop, agent-codex-laptop, agent-opencode-laptop, agent-hermes-laptop and agent-antigravity-laptop. They start with enabled = false.

The running server reads the change by itself: there is nothing to restart. uv run jezero device list shows the laptop with its connectors.

5. Check the connection (on the laptop)

python3 ~/.jezero-src/jezero-client/jezero_client.py status

You should see:

key: /home/me/.jezero
server https://YOUR-JEZERO: HTTP 200 {"ok":true,"device":"laptop","version":"0.1.0.dev0"}
queued sessions: 0
rejected uploads: 0

6. Set up Claude Code (on the laptop)

Install the Jezero plugin. It brings the MCP server, the hooks and the jezero skill:

claude plugin marketplace add MarsGotta/jezero
claude plugin install jezero@jezero

You should see:

...
✔ Successfully added marketplace: jezero (declared in user settings)
Installing plugin "jezero@jezero"...✔ Successfully installed plugin: jezero@jezero (scope: user)

Check that Claude Code reaches Jezero:

claude mcp list

You should see, among your other servers:

plugin:jezero:jezero: python3 /home/me/.claude/plugins/.../core/jezero_client.py mcp --agent claude-code - ✔ Connected

The plugin's MCP server is the client core's bridge: it runs on the laptop and adds the key from ~/.jezero to each request, so Claude Code's configuration never holds the key.

The plugin's hooks give every session a short protocol and recent work of its project, add related past work to the first prompt, and upload the session's transcript when it ends. A hook never blocks Claude Code: its network calls time out after a few seconds, and errors go to ~/.jezero/client.log.

7. Work one session (on the laptop)

Start Claude Code in a project, for example ~/projects/atlas:

cd ~/projects/atlas
claude

Give it a real task, let it finish, and leave with /exit. When the session ends, the plugin queues its transcript and uploads it in the background.

Check that it left the laptop:

python3 ~/.jezero-src/jezero-client/jezero_client.py status

You should see queued sessions: 0. A session that could not be sent (offline, server down) stays queued and goes out with the next one.

On the server, the transcript is now in the laptop's inbox, next to a .project file that holds the project the laptop detected:

cd ~/jezero
find data/inbox/laptop/claude-code -type f

You should see:

data/inbox/laptop/claude-code/projects/-home-me-projects-atlas/SESSION-ID.jsonl.project
data/inbox/laptop/claude-code/projects/-home-me-projects-atlas/SESSION-ID.jsonl

The server's log shows the upload as a PUT /inbox/v1/claude-code/projects/... request with 200 OK.

8. Turn the session into an item (on the server)

The inbox holds the raw transcript. A connector reads it, the summarizer writes the item, and the library stores it. That last part calls a language model, so it needs the summarizer.

  1. Ask what a run would do, without calling the model:
uv run jezero run --connector agent-claude-code-laptop --dry-run

Right after the upload you should see "deferred_sessions": 1:

{"connector": "agent-claude-code-laptop", "docs": 0, "unchanged": 0, "stored": 0, "failed": 0, "deferred_sessions": 1, "redactions": 0, "input_chars": 0, "input_tokens": 0, "output_tokens": 0, "pruned": 0, "dry_run": true, "sample": false, "note": "nothing to summarise (1 still active, deferred)", "errors": [], "warnings": []}

A connector waits until a session has been quiet for 30 minutes (the option settle_minutes), so it never summarises a session that is still growing. The clock starts at the upload. Come back after 30 minutes and run the same command. You should see the session counted as work:

{"connector": "agent-claude-code-laptop", "docs": 1, "unchanged": 0, "stored": 0, "failed": 0, "deferred_sessions": 0, "redactions": 0, "input_chars": 1208, "input_tokens": 0, "output_tokens": 0, "pruned": 0, "dry_run": true, "sample": false, "note": null, "errors": [], "warnings": []}

input_chars is the size of what would go to the model, after cleaning; yours differs.

  1. Give the server a summarizer, if it has none. Add to jezero.toml, with a small, fast model of your provider:
[summarizer]
provider = "anthropic"
model = "MODEL"
api_key_env = "JEZERO_SUMMARIZER_API_KEY"

Put the key in a file named .env next to jezero.toml (git ignores it):

JEZERO_SUMMARIZER_API_KEY=YOUR-API-KEY

Check that Jezero sees it:

uv run jezero check-config

You should see, at the end:

environment variables (values never shown):
  - JEZERO_SUMMARIZER_API_KEY: set

Other providers and options are in Configuration.

  1. Run a pilot on the newest sessions:
uv run jezero run --connector agent-claude-code-laptop --sample 3

You should see "stored": 1:

{"connector": "agent-claude-code-laptop", "docs": 1, "unchanged": 0, "stored": 1, "failed": 0, "deferred_sessions": 0, "redactions": 0, "input_chars": 1208, "input_tokens": ..., "output_tokens": ..., "pruned": 0, "dry_run": false, "sample": true, "note": null, "errors": [], "warnings": []}

Without a summarizer, the run stops with "error": "SummarizerError: summarizer.model is not set in the config" as soon as a session is ready to summarise.

  1. The pilot ("sample": true) changes nothing in the connector's state: no cursor, no last run. Turn the connector on so every run reads the laptop's new sessions: in jezero.toml, find the [[connectors]] block with name = "agent-claude-code-laptop" and change its enabled = false to enabled = true. Then run every enabled connector once:
uv run jezero run

You should see the session reported as "unchanged": 1: the pilot already stored it, and Jezero summarises a session again only when its content changes.

From now on, jezero run --due on a timer collects the laptop's sessions without you. See Run Jezero as a service.

9. Search it (on both computers)

On the server, jezero search sees every source. Search with a few distinctive words of your session:

uv run jezero search "WORDS"

You should see a line with the new source and the project:

[4]   1.714  2026-10-21  agent-claude-code-laptop  atlas  TITLE

The title, summary and atoms are what the summarizer wrote; jezero show 4 (or the app) shows them.

On the laptop, Claude Code finds the item too. Start a new session in any folder and ask about the work you did, for example "What did we change in atlas today? Check Jezero." The agent calls search and cites the item id.

To search from the laptop's terminal, install the jezero command there. It reads with the laptop's key, so it sees the same sources as its agents:

uv tool install git+https://github.com/MarsGotta/jezero
jezero find WORDS

You should see:

 #4  TITLE
      ✻ atlas · 12 h ago

1 results · jezero show ID for the whole memory

If jezero is not found, add ~/.local/bin to your PATH. The laptop reads only agent-* sources: if the server holds the demo items of the first tutorial, they do not appear here.

What you built

  • A laptop with its own key in ~/.jezero, approved on the server as the client laptop.
  • Claude Code on the laptop with the Jezero MCP server, the hooks and the skill.
  • A connector, agent-claude-code-laptop, that turns the laptop's uploaded sessions into items.

Next steps