# Opp Repl MCP Server

> Connect an AI agent to opp_repl via its built-in Model Context Protocol (MCP) server. Two transports — a Unix domain socket reached through the `opp_repl_mcp_bridge` stdio bridge (recommended for local tools like Claude Code, Cursor, VS Code, Windsurf) and a TCP/streamable-HTTP port with bearer-token auth (for remote/legacy clients). Exposes the `execute_python` tool plus opp-repl:// documentation resources. Load when wiring opp_repl into an MCP-capable client.

- Skill: `tabgab/opp-repl-mcp-server` (Agent Skill)
- Install (CLI): `npx skillmds@latest add tabgab/opp-repl-mcp-server`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tabgab/opp-repl-mcp-server/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-mcp-server

---


# MCP server for AI assistants

opp_repl ships an MCP server that lets an AI assistant execute
Python in the live IPython session and browse auto-generated
documentation resources.  It speaks **two transports**:

1. **Unix domain socket** (`--mcp-socket`) — recommended for local
   use.  No token; access is controlled by `0600` file permissions.
   AI tools connect through the **`opp_repl_mcp_bridge`** stdio
   bridge, which most MCP clients launch for you.
2. **TCP / streamable-HTTP** (`--mcp-port`) — for remote clients or
   ones that only speak HTTP.  Requires a bearer token (or an
   explicit bypass) outside `opp_sandbox`.

Upstream reference:
https://github.com/omnetpp/opp_repl/blob/main/doc/mcp_server.md

## Requirements

    pip install "opp_repl[mcp]"

## The MCP server is OFF by default

`--mcp-port` defaults to `0` (disabled) and `--mcp-socket` is unset.
You must explicitly enable one of them; they are **mutually
exclusive** (passing both is an error).

## Transport 1 — Unix domain socket (recommended, local)

Start the REPL with a socket:

    opp_repl --mcp-socket --load "etc/*.opp"          # default per-user path
    opp_repl --mcp-socket /tmp/opp_repl/mcp.sock ...  # explicit path

- Default path: `$XDG_RUNTIME_DIR/opp_repl/mcp.sock`, falling back to
  `/tmp/opp_repl-<uid>/mcp.sock`.
- No bearer token — the socket's `0600` permissions are the access
  control.  `--mcp-token-hash` / `--mcp-bypass-token-hash-check` are
  **rejected** with `--mcp-socket`.

AI clients reach the socket through the stdio bridge:

    opp_repl_mcp_bridge                       # default socket path
    opp_repl_mcp_bridge --mcp-socket <path>   # explicit path

`opp_repl_mcp_bridge --help` prints the resolved default path and
ready-to-paste client config snippets.

## Transport 2 — TCP / streamable-HTTP (remote, legacy)

    # Generate a token hash (Linux: sha256sum, macOS: shasum -a 256)
    TOKEN=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')
    HASH=$(printf '%s' "$TOKEN" | shasum -a 256 | cut -d' ' -f1)

    opp_repl --mcp-port 9966 --mcp-token-hash "$HASH" --load "etc/*.opp"

- Endpoint: `http://127.0.0.1:9966/mcp` (stateless streamable HTTP).
- Clients send `Authorization: Bearer <TOKEN>` (the raw token, not
  the hash).
- Outside `opp_sandbox`, starting TCP mode without `--mcp-token-hash`
  AND without `--mcp-bypass-token-hash-check` raises an error.
- `--mcp-bypass-token-hash-check` disables auth (trusted networks
  only).  Inside `opp_sandbox` the auth requirement is waived
  automatically — see `opp-repl-sandbox`.

## Tool: `execute_python(code: str) -> str`

The only MCP tool.  Runs `code` in the SAME IPython namespace the
interactive user sees — all opp_repl functions, every loaded
project's `{name}_project` variable, and any prior session state.

Returns the repr of the last expression (if any) followed by
captured stdout/stderr/logging; output is also streamed to the
client as log notifications and printed to the REPL console live.
Per the tool's own guidance: **read the documentation resources
first, don't guess signatures, and don't `print()` just to view a
value** (the last expression's repr is returned automatically).

## Resources

| URI                                            | Description                                  |
|------------------------------------------------|----------------------------------------------|
| `opp-repl://guides`                            | List guide topics with 1-paragraph summaries |
| `opp-repl://guide/{topic}`                     | One guide (e.g. `fingerprint_tests`)         |
| `opp-repl://packages`                          | List sub-packages with summaries             |
| `opp-repl://package/{package_name}`            | Package docstring + per-class summaries      |
| `opp-repl://class/{class_name}`                | Full class doc + method signatures           |
| `opp-repl://method/{class_name}/{method_name}` | One complete method docstring                |
| `opp-repl://function/{function_name}`          | One complete function docstring              |

Names can be fully qualified
(`opp_repl.simulation.workspace.SimulationWorkspace`) or short
(`SimulationWorkspace`).

## Client configuration

### Claude Code (recommended)

    claude mcp add --transport stdio opp_repl -- opp_repl_mcp_bridge

…or add to `.mcp.json` (project) / `~/.claude.json` (user):

```json
{
  "mcpServers": {
    "opp_repl": { "type": "stdio", "command": "opp_repl_mcp_bridge" }
  }
}
```

### Windsurf (`~/.codeium/windsurf/mcp_config.json`)

```json
{ "mcpServers": { "opp_repl": { "command": "opp_repl_mcp_bridge" } } }
```

### VS Code / Cursor (`.vscode/mcp.json`)

```json
{ "servers": { "opp_repl": { "type": "stdio", "command": "opp_repl_mcp_bridge" } } }
```

### TCP fallback (any HTTP MCP client)

```json
{
  "mcpServers": {
    "opp_repl": {
      "url": "http://localhost:9966/mcp",
      "headers": { "Authorization": "Bearer <your_token>" }
    }
  }
}
```

Pass `--mcp-socket <path>` in the bridge's `args` (or
`opp_repl_mcp_bridge --mcp-socket <path>`) when the REPL uses a
non-default socket path.

## Recommended discovery flow for an AI agent

1. `opp-repl://guides` → which task-level guides exist.
2. `opp-repl://guide/{topic}` → concrete examples.
3. `opp-repl://packages` → find the relevant sub-package.
4. `opp-repl://package/{name}` → compact API overview.
5. `opp-repl://class/...` / `opp-repl://function/...` → full signatures.
6. `execute_python(...)` with the chosen approach.

## Pitfalls

- The session is LIVE and STATEFUL — state persists across
  `execute_python` calls.  Two agents on one server stomp on each
  other; run one REPL per agent, or share deliberately (see
  `opp-repl-shared-terminal`).
- `execute_python` runs arbitrary code as you.  Treat the endpoint
  as privileged; never expose TCP mode on a public network
  unauthenticated.  For isolation, run inside `opp_sandbox`.
- In CI / parallel test runs, leave the MCP server OFF (the default)
  — don't pass `--mcp-port` / `--mcp-socket`.
- Closing the MCP client does NOT reset the REPL; the kernel keeps
  its state until the process exits.

## See also

- `opp-repl-shared-terminal` — one live REPL driven by a human (tmux)
  AND an AI (MCP) at once.
- `opp-repl-sandbox` — run the MCP server under bubblewrap isolation.
- `opp-repl-repl-usage` — driving the same kernel from a terminal.
- `opp-repl-ai-workflows` — end-to-end recipes for AI integration.
- `opp-repl-overview` — map of which skills to load when.

