Skip to main content

repld

A live Python kernel for your agent. Shared namespace, channel push, a scriptable browser, and one-off code that hardens into tools.

uv tool install repld-tool

What it does

  • Persistent kernel — one long-running Python process in your project directory. State survives across turns.
  • Shared namespace — you and the agent operate on the same __main__. Inspect its variables, patch its functions, take over mid-task.
  • Channel push — long jobs, timers, file watchers, and webhooks push back as notifications. The agent reacts; it never polls.
  • Browser — attach to your logged-in Chrome via CDP. Every mutation settles, then returns the accessibility tree, network delta, and console delta.
  • Gists — plain Python files the kernel hot-reloads. Reverse-engineer an API once, import it forever, link it across projects, register it as an MCP tool.

Install

uv tool install repld-tool        # global install (recommended)

cd your-project
claude mcp add repld -- repld bridge   # register it with the client

# channel push is a research preview, so it takes a development flag
claude --dangerously-load-development-channels server:repld

You don't have to start the kernel yourself: repld bridge spawns a headless one for the project if none is running, and restarts it if it dies. Run repld in a terminal when you want the live display instead — either way, repld log -f tails it, repld status shows what's running, repld tasks lists in-flight defer() tasks and @every tickers (repld tasks wait <id> / cancel <id> block on or stop one), and repld stop shuts it down. Runtime state lives under $XDG_RUNTIME_DIR/repld/, so nothing lands in your project directory and there's nothing to .gitignore.

Coming from 0.1.x, that last part is new, and the files the old version wrote into your projects are still there — see Upgrading to 0.2.

For browser integration, start the kernel with repld browser instead of repld — it re-execs under uv run with the browser extra (duckdb, websockets, pillow) for that invocation, so no project changes are needed. Or install the extra permanently with uv tool install repld-tool[browser].

Quick example

# runs inline — result returned immediately
import httpx
httpx.get("https://api.example.com/status").json()

# long-running — returns task_id, pushes channel notification on completion
await asyncio.sleep(30)
notify("done", kind="migration")

Autonomous worker:

@every(300)
async def check_overdue():
    for inv in await erp.get_overdue():
        notify(f"Overdue: {inv.customer} — {inv.amount}",
               kind="overdue", invoice_id=inv.id)

The kernel runs the watcher; the agent reacts to each channel notification.

With an existing app

repld inherits your project's environment. A repld_init.py at the project root is executed into __main__ when a kernel boots — by every kernel for that project, including the headless one the bridge starts for you:

from myapp.main import app
from myapp.db import async_session_maker
import asyncio, uvicorn

asyncio.create_task(uvicorn.Server(
    uvicorn.Config(app, host="127.0.0.1", port=8000, log_level="warning")
).serve())

session = async_session_maker()
print("FastAPI on :8000, db session ready")

Nothing to pass — open claude (or run repld for the live display) and the agent has a live handle on your running app: inspect routes, query the ORM, call handlers directly.

Tools

Core:

Tool What it does
exec Execute Python. Returns inline within timeout (default 2s); otherwise returns task_id and pushes channel on completion.
get_task Status + head/tail preview of a running task's output.
cancel Cancel a running task by id.
repld_restart Restart the kernel, discarding in-memory state. The MCP session survives — the bridge respawns and replays the handshake. Not needed for gist edits; those auto-reload.

repld_restart is served by the bridge rather than the kernel, since a kernel can't answer "restart yourself" without the reply dying in flight.

Browser (run repld browser instead of repld, or uv tool install repld-tool[browser]):

Tool What it does
browser_watch Watch URL pattern, auto-attach matching tabs.
browser_tabs List attached tabs.
browser_pages List all Chrome targets.
browser_js Evaluate JavaScript (REPL semantics, top-level await).
browser_network Query captured traffic (HAR-style, DuckDB).
browser_request Full HAR entry — headers, postData, timing.
browser_body Response body for a captured request.
browser_fetch In-page fetch (inherits auth/cookies).
browser_click Click element (auto-waits, returns observation).
browser_type Type into element.
browser_select Select an option in a dropdown or custom listbox widget.
browser_hover Move the mouse over an element and leave it parked there.
browser_drag Press, drag, and release across two selectors or points.
browser_key Send key press (Enter, Escape, etc).
browser_navigate Navigate tab to URL.
browser_open Open new tab and navigate.
browser_tree Accessibility tree snapshot.
browser_console Query console logs and exceptions.
browser_screenshot Capture page screenshot.
browser_cdp Raw CDP passthrough.
browser_clear Reset captured network/console.
browser_detach Remove watch pattern, detach tabs.
browser_controls Discover a page's window.controls schema.
browser_invoke Invoke a control action, with the full observation pipeline.
browser_set_files Resolve an open native file-chooser prompt with local paths.
browser_expect_file_chooser Pre-arm paths for a file chooser a following action will open.
browser_expect_auth Pre-arm credentials for an HTTP Basic/Digest auth prompt.
browser_grant_permissions Pre-authorize camera/mic/geolocation/etc for an origin.
browser_dismiss_dialog Dismiss or accept a native alert/confirm/prompt dialog.

Output from every cell spills to $XDG_RUNTIME_DIR/repld/ — the inline response carries a head/tail preview plus the spill path. Use standard Read/Grep tools for full output.

Kernel builtins

notify(content, **meta)        # channel push to the agent
await ask(prompt)              # block on free-form human input
await confirm(prompt)          # block on yes/no
await choose(prompt, options)  # block on pick-one
defer(coro, label=None)        # fire-and-forget, channel push on completion
@every(seconds)                # periodic ticker, fn.cancel() to stop

A kernel you started with repld takes gate answers in its own pane, and a pinned browser tab takes them through its pill. The headless kernel the bridge spawns has neither, so it says so in the notification — repld gate lists what's pending and repld gate answer <id> <value> resolves it.

Browser

repld[browser] attaches to Chrome via CDP (--remote-debugging-port=9222, Chrome 140+). You log in normally; the agent sees your traffic, discovers the API surface, and works with your authenticated sessions.

tab = await browser.get("*example.com*")  # find tab by URL glob
tab = await browser.open("https://...")   # open new tab
await browser.watch("*pattern*")          # auto-attach matching tabs

await tab.js("document.title")           # eval JS (top-level await works)
await tab.fetch("/api/data")             # in-page fetch (inherits session)
await tab.click("#submit")               # click, settle, return observation
await tab.type_text("#search", "query")  # type into element
tab.network(url="*api*")                 # query captured traffic

Body capture via Fetch interception means login flows, redirects, and CSRF exchanges are never lost. See docs/browser.md for the full design.

Gists

Gists are Python modules in ./gists/ (project) or ~/.repld/gists/ (global) that wrap anything into a callable API. The browser supplies auth; the gist captures the pattern.

# gists/myapp.py
"""MyApp — accounts and transactions."""

class MyApp:
    def __init__(self, tab): self._tab = tab

    @classmethod
    async def connect(cls):
        from __main__ import browser
        tab = await browser.get("*myapp.com*")
        return cls(tab)

    async def accounts(self):
        return (await self._tab.fetch("/api/accounts"))["body"]
from myapp import MyApp
app = await MyApp.connect()
await app.accounts()

Re-importing after edits auto-reloads. Gists can declare dependencies (__repld_deps__), register MCP tools (typed _tool_* functions, with Annotated[T, "..."] for per-parameter descriptions), and link across projects (repld gist add <name>). repld gist fetch <gist-url> copies someone else's gist in, and repld gist lint checks all of it. See repld help gists for details.

Scope

repld executes arbitrary Python in your project environment. It is a dev-time tool — never a runtime dependency. The IPC socket is localhost-only with user-only permissions.

Channel push is a research preview, so it takes a development flag: claude --dangerously-load-development-channels server:repld.

License

MIT. The browser extra vendors Playwright's injected-script engine (Apache-2.0) — see THIRD_PARTY_LICENSES.md.

Release files for repld-tool 0.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for repld-tool 0.10.1
File Size Uploaded
repld_tool-0.10.1.tar.gz 417.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for repld-tool 0.10.1
File Interpreter ABI Platform
repld_tool-0.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 870.2 kB

Release files / repld_tool-0.10.1.tar.gz

Download URL repld_tool-0.10.1.tar.gz
Size 417.5 kB
Tags Source
SHA-256 checksum
How to use checksums
072e2fec56888b55ccca4af57fcd84c159eb29418261e8b55f487cc4beec81a3
BLAKE2b-256 checksum
How to use checksums
8851b5c7642da4f6add27e560ba5fb9698ceea6e0229669c2c8d0d3728b94da6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / repld_tool-0.10.1-py3-none-any.whl

Download URL repld_tool-0.10.1-py3-none-any.whl
Size 452.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
154bd48d0136f192a1991f8d105571f5d25de5f675dcf980a012983cf9cf4dfb
BLAKE2b-256 checksum
How to use checksums
eaf8badbc0aed345593091c54a7ad4cdbc5328d1f663eaf93a8cef7fea507c7c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.10.7

2 release files

0.10.6

2 release files

0.10.5

2 release files

0.10.4

2 release files

0.10.3

2 release files

0.10.2

2 release files

This release

0.10.1 This release

2 release files

0.10.0

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.24

2 release files

0.0.23

2 release files

0.0.22

2 release files

0.0.21

2 release files

0.0.20

2 release files

0.0.19

2 release files

0.0.18

2 release files

0.0.17

2 release files

0.0.16

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page