Skip to main content
ClaudeWave

Leased dev environments for AI coding sessions — every server dies when its session ends, so none are left running rogue. MCP server + CLI.

MCP ServersRegistry oficial0 estrellas0 forks● PythonApache-2.0Actualizado today
ClaudeWave Trust Score
95/100
✓ Verified
Passed
  • ✓Open-source license (Apache-2.0)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Last scanned: 9/29/2026
Install in Claude Code / Claude Desktop
Method: UVX (Python) · rentctl
Claude Code CLI
claude mcp add rentctl -- uvx rentctl
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "rentctl": {
      "command": "uvx",
      "args": ["rentctl"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Casos de uso

Resumen de MCP Servers

# rentctl

<!-- mcp-name: io.github.Michael-Drake/rentctl -->

**A dev server should never outlive the work that needed it.**

`rentctl` *rents* dev environments to your AI coding sessions. Every environment is a
**lease**: it dies when the session ends, when the lease expires, or when you say so —
whichever comes first. Cleanup is owned by code, not by an agent remembering to clean up.

Ships as both a CLI (`rent`) and an MCP server, so an agent can start and stop
environments through tools instead of shelling out to a raw `npm run dev` it will forget
about.

## Why

An AI coding session starts a dev server. Then the session ends — crashes, is closed, or
just moves on — and the server keeps running. By Friday there are six of them, three are
on ports you've forgotten, and one is quietly serving stale code that makes a bug look
unreproducible.

Telling the agent to clean up doesn't fix this, because the failure mode *is* the agent
not doing what it was told. `rentctl` makes the cleanup structural: the environment has an
expiry, and something other than the agent enforces it.

## Install

```
uv tool install rentctl        # or: pipx install rentctl, or: pip install rentctl
```

Requires Python 3.12+. **macOS and Linux.** There is no Windows support and no Windows
claim — process-group teardown is the safety-critical mechanism here, and it has no
tested Windows equivalent yet.

## First run

A framework-free server, so nothing but Python is involved. In a scratch repo:

```
mkdir hello && cd hello && git init -q
cat > rentctl.toml <<'EOF'
[project]
name = "hello"
runner = "process"

[profiles.default]
cmd = 'python3 -m http.server --bind 127.0.0.1 "$PORT"'
cwd = "."
port_env = "PORT"
EOF
rent init
```

`init` shows you exactly what it will run and waits for an explicit yes:

```
Enroll project 'hello' (runner: process)
  source:     /home/you/hello
  port block: 6200-6209

rentctl will run these commands on your behalf:
  [default]
    command: python3 -m http.server --bind 127.0.0.1 "$PORT"
    in:      /home/you/hello
    port via $PORT

Approve and enroll? [y/N] y
```

Your block will differ — blocks are drawn from 5100 upward, lowest free first. Then:

```
$ rent up hello
{
  "ok": true,
  "project": "hello",
  "url": "http://localhost:6200",
  "port": 6200,
  "lease_expires": "2026-09-28T13:32:36.428730-05:00",
  "already_running": false,
  "readiness": "answered",
  …
}

$ rent ls                      # one row: hello, port 6200, "healthy": true
$ curl -sI http://localhost:6200/
HTTP/1.0 200 OK

$ rent down --all --cwd .      # exactly what the SessionEnd hook runs
{
  "ok": true,
  "downed": [ { "project": "hello", "port": 6200, "was_running": true, … } ]
}

$ curl -sI http://localhost:6200/ || echo gone
gone
```

(Output trimmed where marked `…`.) That last step is the whole product: in an enrolled
Claude Code or Gemini CLI session you never type `rent down` — the session ending does.
`rent events --summary` afterwards shows the teardown and which cleanup layer did it.

If something doesn't behave, see [Troubleshooting](#troubleshooting).

## Enroll a project

A project describes itself in a `rentctl.toml` at its repo root (a `devctl.toml`
left over from before the rename is still read, so nothing needs renaming to keep
working):

```toml
[project]
name = "myapp"          # lowercase, no separators — it is used as a filename
runner = "process"

[profiles.default]
cmd = 'npm run dev -- --port "$PORT" --strictPort'
cwd = "frontend"        # repo-relative, never absolute
port_env = "PORT"       # rentctl sets this in the child's environment
```

Then, from the repo:

```
rent init
```

`init` shows you the exact command it will run, asks you to approve it, claims a block of
ports for the project, registers the MCP server, installs the cleanup hooks (unless the
Claude Code plugin already supplies them), and adds a short rule to `CLAUDE.md` /
`GEMINI.md` telling agents to start servers through rentctl rather than by hand. Nobody
else has to edit anything.

**There is no port field.** Ports are drawn when a server starts, not written down in a
tracked file — so two checkouts of the same repo get different ports instead of fighting,
and a config file can't hand out a number the allocator never heard of. Each project owns
a contiguous block of 10 ports.

## Use

```
rent up myapp              # start (or renew) — prints the URL and the port
rent down --all --cwd .    # stop everything leased to this directory
rent ls                    # every environment on this machine
rent sweep                 # reconcile: stop what's expired or dead
rent events --summary      # what happened, and which cleanup layer did it
rent sync                  # re-approve a changed rentctl.toml
rent doctor                # are the shims, registry and hooks actually working?
rent report-kill myapp --note "…"   # "you killed something I was using"
```

`report-kill` exists because `rentctl` cannot tell, on its own, whether a teardown
was unwanted — a kill you asked for and a kill you regret look identical from the
inside. The report lands in the same append-only log as everything else and is
matched to the teardown it disputes, so an unwanted kill becomes a fact on the
record rather than an anecdote.

Leases default to **120 minutes** and are capped at **480**. `rent up` on a live lease
renews it rather than starting a second server.

## Which clients get automatic cleanup

| Client | How it is wired | Session-end cleanup |
|---|---|---|
| Claude Code | the plugin, or `rent init` (`.mcp.json` + `.claude/settings.local.json`) | **Yes** — SessionEnd runs `rent down --all --cwd "$CLAUDE_PROJECT_DIR"`; SessionStart runs `rent sweep` |
| Gemini CLI | `rent init` (`.gemini/settings.json`), when Gemini is used in the project or installed | **Yes** — same hooks, scoped by `$GEMINI_PROJECT_DIR` |
| Any other MCP client | register `rent-mcp` yourself | **No** — lease expiry and sweep only |
| A plain shell | `rent` | **No** — lease expiry and sweep only |

"Expiry and sweep only" still guarantees the server dies — just at the end of its lease
(120 minutes by default), not when you close the window.

**Plugin-only installs need the CLI too.** The Claude Code plugin calls the `rent` and
`rent-mcp` you installed with `uv tool install rentctl`; it does not bundle them, and it
deliberately does not fetch its own copy — a second, different rentctl acting on the same
leases is worse than none. Without `rent` on `PATH`, session-end cleanup is **off**: every
session then starts with a warning saying so and naming the install command. Install the
package first, then run `rent doctor`, which reports whether each project's hooks come
from the plugin, from `settings.local.json`, or from both.

**From the MCP Registry**, a client runs `uvx rentctl@<version>`: the `rentctl`
executable is the MCP server, the same as `rent-mcp` (typed in a terminal it waits for a
client on stdin). That gives you the tools with expiry-and-sweep cleanup only — the
hooks come from the plugin or `rent init`. `rent --version` says which version you are
running.

## How cleanup actually happens

Four independent layers, so no single failure leaves an orphan:

1. **You ask** — `rent down`.
2. **The session ends** — a `SessionEnd` hook tears down everything leased to that
   directory.
3. **The lease expires** — a detached watchdog per lease kills it after expiry, even if
   the session died without running its hook. It checks once a minute, so teardown lands
   up to ~60 s after the lease runs out, not at the instant.
4. **The next sweep** — `rent sweep` (which the hooks also run at session start) stops
   anything expired or already dead that the first three missed.

**A crashed session is cleaned up by layers 3 and 4, not 2.** If the session dies
without firing its hook, its server keeps running until the lease expires — up to the
full lease length. Shorter leases (`rent up myapp --lease-minutes 30`) shorten that
window. A sweep does not stop a live, unexpired lease; it cannot tell a crashed session
from one that is still working.

There is **no daemon.** State lives on disk and the OS process table is the source of
truth, so there is no background service to babysit, and nothing to resurrect after a
reboot.

### One active session per checkout

A lease belongs to a **(project, directory)** pair, not to a session. Two agent sessions
open in the *same* checkout share one environment — the second `rent up` renews the
first's server rather than starting its own — and the first session to end runs
`rent down --all --cwd` and tears it down under the other.

Separate git worktrees avoid this entirely: each worktree is its own directory, gets its
own lease and its own port, and its session end touches only its own server. Shared
sessions in one checkout are a known limitation, with no fix promised yet.

### It won't kill things it doesn't own

Every lease records the process's PID **and its start time**. Before killing anything,
`rentctl` re-checks both. If the PID was recycled onto some unrelated process, the start
times disagree and it refuses — a stale lease can't get your database killed.

A listener inside an enrolled project's port block with no lease behind it is a
**squatter**. What happens to it depends on the machine's enforcement mode:

- **advisory** (the default, and the only mode any command sets) — `rent up` routes
  around it, and `rent ls` / `rent sweep` report it. It is never signalled.
- **strict** — `rent sweep` sends each squatter `SIGTERM`, and reports what it killed.
  Since the session-start hook runs `rent sweep`, under strict that happens at every
  session start. Strict is set by the `enforcement` field in rentctl's machine-local
  registry; nothing turns it on for you. See
  [Development machines only](#development-machines-only) before you do.

When it genuinely cannot tell whether a port is in use — no usable probe on the host —
it says so, rather than report
ai-agentsclidev-servermcpprocess-management

Lo que la gente pregunta sobre rentctl

¿Qué es Michael-Drake/rentctl?

+

Michael-Drake/rentctl es mcp servers para el ecosistema de Claude AI. Leased dev environments for AI coding sessions — every server dies when its session ends, so none are left running rogue. MCP server + CLI. Tiene 0 estrellas en GitHub y su última actualización registrada es del 2026-09-29.

¿Cómo se instala rentctl?

+

Puedes instalar rentctl clonando el repositorio (https://github.com/Michael-Drake/rentctl) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar Michael-Drake/rentctl?

+

Nuestro agente de seguridad ha analizado Michael-Drake/rentctl y le ha asignado un Trust Score de 95/100 (tier: Verified). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene Michael-Drake/rentctl?

+

Michael-Drake/rentctl es mantenido por Michael-Drake. La última actividad registrada en GitHub es del 2026-09-29, con 0 issues abiertos.

¿Hay alternativas a rentctl?

+

Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.

Despliega rentctl en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: Michael-Drake/rentctl
[![Featured on ClaudeWave](https://claudewave.com/api/badge/michael-drake-rentctl)](https://claudewave.com/repo/michael-drake-rentctl)
<a href="https://claudewave.com/repo/michael-drake-rentctl"><img src="https://claudewave.com/api/badge/michael-drake-rentctl" alt="Featured on ClaudeWave: Michael-Drake/rentctl" width="320" height="64" /></a>

Más MCP Servers

Alternativas a rentctl