# Opp Repl Shared Terminal

> Run opp_repl inside a shared tmux session with its MCP server exposed, so a human (attached to tmux) AND an AI assistant (Claude Code, Windsurf, Cursor, VS Code) drive the SAME live IPython/OMNeT++ namespace at once. Default transport is a Unix domain socket reached via opp_repl_mcp_bridge; a TCP+bearer-token mode is available for remote clients. Bundled scripts start/attach/stop the session and write the client config. Load when the user wants to co-pilot one persistent opp_repl session with an AI.

- Skill: `tabgab/opp-repl-shared-terminal` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add tabgab/opp-repl-shared-terminal`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tabgab/opp-repl-shared-terminal/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: tabgab (https://skillmd.com/u/tabgab)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tabgab/opp-repl-shared-terminal

---


# opp_repl shared-terminal mode (tmux + MCP)

This skill stands up a **single opp_repl process** driven concurrently
by two clients:

- the **human user**, who `tmux attach`es and types at the live
  IPython prompt;
- an **AI assistant** (Claude Code, Windsurf, Cursor, VS Code, or any
  MCP client), which calls the `execute_python` MCP tool.

Because `execute_python` runs in the **same IPython namespace** as the
interactive user, all state (loaded projects, results, variables,
imports) is genuinely shared — no context drift between what the user
sees and what the AI sees. It is one process.

This composes the base pack (`opp-repl-mcp-server`, `opp-repl-repl-usage`)
into a collaboration workflow; load those for the underlying details.

## When to use

- "I want Claude Code and me to share one opp_repl terminal."
- The AI should inspect/extend simulation work the user is doing live,
  or the user should watch and steer what the AI runs.
- One persistent OMNeT++ session that survives closing the AI client
  or terminal emulator.

For plain single-user opp_repl, use `opp-repl-repl-usage`. For the MCP
transport details and per-client config, see `opp-repl-mcp-server`.

## Architecture

```
        ┌────────────────────────────────────┐
        │   tmux session: opp_repl           │
        │  ┌──────────────────────────────┐  │
 user ─►│  │  opp_repl (IPython)          │  │   stdio    ┌───────────────┐
attach  │  │   --mcp-socket <path>        │◄─┼── bridge ──┤ opp_repl_     │◄─ AI client
        │  │   --load ...                 │  │  (UDS)     │ mcp_bridge    │  (Claude Code,
        │  └──────────────────────────────┘  │            └───────────────┘   Windsurf, …)
        └────────────────────────────────────┘
```

- One opp_repl process; tmux owns its PTY so the user can attach.
- Default: opp_repl listens on a **Unix domain socket**; AI clients
  spawn `opp_repl_mcp_bridge` (stdio↔socket). No token needed —
  the socket's `0600` permissions are the access control.
- Fallback: `--http [PORT]` exposes streamable HTTP on `127.0.0.1`
  with a bearer token, for remote clients or older opp_repl.

## Prerequisites

- opp_repl installed with the MCP extra: `pip install "opp_repl[mcp]"`
  (`opp_repl` and `opp_repl_mcp_bridge` on PATH after sourcing the
  OMNeT++ `setenv` / activating the venv).
- `tmux` installed.
- The AI client runs on the **same host** (socket and TCP both bind
  locally). For a remote client, forward over SSH and keep auth on.

## Files in this skill

- `scripts/start_shared_repl.sh` — start opp_repl in tmux with the MCP
  server, wait for it, and write the AI client's config. Socket
  transport by default; `--http [PORT]` for TCP+token.
- `scripts/attach_repl.sh` — `tmux attach` to type at the live prompt
  (`--read-only` to watch only).
- `scripts/stop_repl.sh` — graceful shutdown (sends `exit`, then kills
  the session if it lingers); shreds the token / removes the socket.
- `scripts/configure_mcp_client.sh` — (re)write a client's MCP config
  for Claude Code / Windsurf / VS Code without restarting the REPL.
- `templates/claude_code_mcp.json`, `templates/windsurf_mcp_config.json`
  — reference config shapes.

All scripts are POSIX-bash and work on Linux and macOS.

## Procedure

### 1. Verify prerequisites

```bash
command -v tmux opp_repl opp_repl_mcp_bridge
echo "$OMNETPP_ROOT"   # source the OMNeT++ setenv first if unset
```

### 2. Start the shared session

From this skill directory:

```bash
scripts/start_shared_repl.sh \
    [--session-name opp_repl] \
    [--load '<.opp glob>' ...] \
    [--client claude|windsurf|vscode|none] \   # default: claude
    [--http [PORT]] \                          # default: Unix socket
    [--detach]
```

Defaults: socket transport, client `claude`, and — when no `--load` is
given — `$OMNETPP_ROOT/omnetpp.opp` + `$OMNETPP_ROOT/samples/*/*.opp`,
or the bundled `--load @opp` descriptors. Without `--detach` you are
attached to tmux immediately.

The script:
1. Aborts if a tmux session of that name exists (stop it first, or use
   a different `--session-name`).
2. Socket mode: picks `~/.opp_repl_shared/mcp-<session>.sock` and runs
   `opp_repl --mcp-socket <path> --load …`. HTTP mode: mints a token,
   passes its SHA-256 via `--mcp-token-hash` (or
   `--mcp-bypass-token-hash-check` on older opp_repl).
3. Polls the endpoint until it answers (socket via `curl --unix-socket`).
4. Writes the chosen client's MCP config (see step 4).
5. Attaches you to tmux (unless `--detach`).

### 3. Attach from any terminal

```bash
scripts/attach_repl.sh            # read-write
scripts/attach_repl.sh --read-only
```

Detach with `Ctrl-b d`. Multiple terminals may attach at once; every
keystroke is visible to the AI because they share one kernel.

### 4. Point the AI client at the session

`start_shared_repl.sh` already wrote the config for `--client`
(default Claude Code → a project `.mcp.json`). To (re)configure later,
or target a different client:

```bash
scripts/configure_mcp_client.sh --client claude    # or windsurf | vscode
```

Then reload the client:
- **Claude Code**: restart / reload the window (or
  `claude mcp add --transport stdio opp_repl -- opp_repl_mcp_bridge`).
- **Windsurf**: restart or "Refresh MCP servers".
- **VS Code/Cursor**: reload the window.

The `opp_repl` server should expose the `execute_python` tool and the
`opp-repl://…` resources.

### 5. Stop the session

```bash
scripts/stop_repl.sh
```

Sends `exit` to IPython (flushes pending writes), waits up to 5 s, then
kills the session if needed, and cleans up the token/socket.

## What is actually shared

- **Python namespace**: yes. `execute_python` runs in the REPL's
  `user_ns` via IPython `run_cell`; variables/imports cross both ways.
- **stdout/stderr**: yes — AI-triggered output appears in the tmux pane
  and its scrollback.
- **Input prompt**: NOT shared. Only the user types at `In [N]:`; the
  AI submits cells over MCP. opp_repl serialises cell execution, so a
  long-running cell on one side queues the other.
- **Working directory / env vars**: shared (one process).
- **Simulation subprocesses**: spawned by opp_repl; a `run_simulations()`
  on one side blocks a conflicting run from the other until it returns.

## Transports

- **Unix socket (default, recommended)**: no token; `0600` perms; AI
  clients use `opp_repl_mcp_bridge`. Best for a local human+AI pair.
- **TCP + token (`--http`)**: streamable HTTP on `127.0.0.1`, bearer
  token in the `Authorization` header. Use for remote clients (over an
  SSH tunnel) or opp_repl builds without the socket transport.

Full details and per-client config shapes are in `opp-repl-mcp-server`.

## Pitfalls

- **Token rotation (HTTP mode)**: every `--http` start mints a new
  token and rewrites the client config — reload the client or it 401s.
- **Stale session / socket**: a crashed REPL can leave the tmux session
  or socket file behind. `stop_repl.sh` cleans both; re-run start after.
- **Bind address**: the socket and TCP port are local. For a remote
  client, forward over SSH (`ssh -L` for TCP, or run the bridge on the
  host) and keep auth on — never expose TCP unauthenticated.
- **opp_repl not on PATH**: the start script sources `$OMNETPP_ROOT/setenv`
  when set; if `OMNETPP_ROOT` is wrong, the env is silently incomplete.
  Always `echo $OMNETPP_ROOT` and `command -v opp_repl` before filing a
  bug.
- **MCP cancellation ≠ Ctrl-C**: the client's "stop" maps to opp_repl's
  cooperative interrupt; it does not instantly kill a running `opp_run`
  subprocess. Use the user-side prompt to `Ctrl-C` an in-flight sim.
- **Non-strict client config**: if the target config has comments or
  trailing commas, the JSON merge refuses to overwrite — fix it by hand
  and re-run `configure_mcp_client.sh`.
- **Config scope**: Claude Code `.mcp.json` is written in the current
  directory (project scope); run start/configure from the workspace you
  drive the AI from, or pass `CLAUDE_MCP_CONFIG=~/.claude.json`.

## Verification

After `start_shared_repl.sh` returns and you're attached:

```python
In [1]: shared_marker = "hello from user"
```

Ask the AI (via chat) to `execute_python("shared_marker")` — it should
return `'hello from user'`. Have it set another variable; re-attach and
confirm it's visible at the prompt.

Without an AI client — hit the endpoint directly:

```bash
# Socket transport:
SOCK=$(cat ~/.opp_repl_shared/socket)
curl -sN --unix-socket "$SOCK" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
          "params":{"name":"execute_python","arguments":{"code":"print(\"mcp ok\")"}}}' \
     http://localhost/mcp

# TCP transport (--http):
TOKEN=$(cat ~/.opp_repl_shared/token)
curl -sN -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json, text/event-stream" \
     -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
          "params":{"name":"execute_python","arguments":{"code":"print(\"mcp ok\")"}}}' \
     http://127.0.0.1:9966/mcp
```

Expect a streaming response containing `mcp ok`; the same line appears
in the tmux pane the user is watching.

## See also

- `opp-repl-mcp-server` — transports, auth, and per-client config.
- `opp-repl-repl-usage` — the interactive REPL the user drives.
- `opp-repl-sandbox` — isolate the shared server under bubblewrap.
- `opp-repl-ai-workflows` — what the AI does once connected.
- `opp-repl-overview` — map of which skills to load when.

