# Use Node Lodge from an AI agent (MCP)

> Let Claude Code, Claude Desktop or your own agent find a GPU, launch a session under a hard spending cap, connect over SSH and stop it.

The Node Lodge MCP server lets an AI agent rent GPU machines for you. The agent lists offers, checks your balance, launches a session with a maximum cost, reads the SSH details and stops the session when the work is done. Every session is paid from your organization credit, and the agent can never spend more than the limits you set on its API key.

It works with any client that speaks the Model Context Protocol (MCP), including Claude Code and Claude Desktop.

## Before you start

- Node.js 22 or newer on the machine that runs the agent.
- Credit on your organization. See [Billing](https://nodelodge.com/docs/billing).
- An SSH key pair. See [SSH keys](https://nodelodge.com/docs/ssh-keys).

## 1. Create a key for the agent

1. In the console, open **Keys** and choose **Create key**.
2. Name it after the agent, for example `claude-code`.
3. Pick the scopes `workloads:read`, `workloads:write` and `billing:read`.
4. Set its **Spending limits**:
   - **Per session**: the most one session can cost.
   - **Total**: the most the key can ever spend.
   - **Calendar month** and **Sessions at a time** are optional.
5. Copy the key. It is shown once.

Node Lodge enforces these limits on its servers, on the budget of each session: a session that would go past one is refused before anything is reserved or started. A running session counts for its whole budget, an ended one for what it was billed. You can lower or raise the limits later with **Edit limits**, after a fresh two-factor code. A lower limit applies to the next session.

## 2. Download the server

```bash
mkdir -p ~/.nodelodge && cd ~/.nodelodge
curl -fsSLO https://nodelodge.com/downloads/nodelodge-mcp.mjs
curl -fsSLO https://nodelodge.com/downloads/nodelodge-mcp.mjs.sha256
sha256sum -c nodelodge-mcp.mjs.sha256
```

On macOS, use `shasum -a 256 -c nodelodge-mcp.mjs.sha256` for the last line. The file is one script, run with Node. Download it again to update.

## 3. Connect your client

### Claude Code

```bash
claude mcp add nodelodge \
  --env NODELODGE_API_KEY=nl_live_... \
  -- node ~/.nodelodge/nodelodge-mcp.mjs
```

Run `claude mcp list` to check that `nodelodge` is connected, or type `/mcp` in a session.

### Claude Desktop

Open **Settings**, then **Developer**, then **Edit Config**, and add the server to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "nodelodge": {
      "command": "node",
      "args": ["/Users/you/.nodelodge/nodelodge-mcp.mjs"],
      "env": { "NODELODGE_API_KEY": "nl_live_..." }
    }
  }
}
```

Use the full path to the file: on Windows, for example `C:\\Users\\you\\.nodelodge\\nodelodge-mcp.mjs`. Restart Claude Desktop. The Node Lodge tools appear in the tools menu of a new chat.

### Over HTTP

For clients that connect to a URL, start the server in HTTP mode on your own machine:

```bash
node ~/.nodelodge/nodelodge-mcp.mjs --http
```

It listens on `http://127.0.0.1:3101/mcp` and stores no key: each request sends its own key as a Bearer token. With Claude Code:

```bash
claude mcp add --transport http nodelodge http://127.0.0.1:3101/mcp \
  --header "Authorization: Bearer nl_live_..."
```

Set `NODELODGE_MCP_PORT` to use another port. The server answers only requests addressed to this machine.

## Tools

| Tool | What it does |
|---|---|
| `list_offers` | Lists Node Lodge Secure machines with GPU, VRAM, CPU, RAM, disk, hourly price in USD, country and city. Filters by GPU model, GPU count, VRAM and price. |
| `get_balance` | Shows the credit available for a new session, what is held and what is owed. |
| `list_environments` | Lists the environments `launch_session` accepts on Node Lodge Secure machines. |
| `launch_session` | Starts a machine with a budget. `max_cost_usd` is required: it is reserved on your credit and the session never costs more. |
| `get_session` | Shows status, cost so far, the launch step under way while the machine starts (`launch_step`) and, once the machine runs, the `ssh` command and how to open JupyterLab. |
| `stop_session` | Stops a session: billing stops and the machine and its disk are deleted. |
| `raise_session_budget` | Raises the budget of a running session to a new `max_cost_usd`, within the limits of the key. |
| `list_sessions` | Lists live or ended sessions. |

### How `max_cost_usd` works

`launch_session` takes `max_cost_usd`, the most the session may cost. It is reserved on your credit at launch as the budget of the session. Billing follows the real time the machine runs, from the moment it is ready, and Budget Guard stops the session before the budget is spent: you are never billed past it. With `duration_hours`, the session also stops after that many hours.

The launch is refused, before anything is reserved or started, when `max_cost_usd` is above your available credit or above a limit of the key. A session stopped early is billed for the time it ran, and the rest of the budget is released. To keep a session running longer, `raise_session_budget` reserves more, under the same checks.

`launch_session` also needs the SSH public key to install on the machine and the public IPv4 address you will connect from (or a range up to /24). Only that address can reach the machine over SSH. The public key opens this session only: it is not saved on your account. `environment_id` is optional, `jupyterlab` by default, the environment data-center machines run.

### JupyterLab

JupyterLab runs on the machine and listens on the machine only. Once the session runs, `get_session` gives `connect.jupyter`: an `ssh_command` that opens the same shell and forwards JupyterLab to port 8888 of your computer, the `url` to open while that connection stays open, and the `token` to type on the sign-in page. The token is a secret: keep it out of addresses and logs. `connect.jupyter` comes to the key that launched the session, with `workloads:write`.

## Resources and prompts

Besides its tools, the server offers read-only **resources** that a client can attach to a conversation:

| Resource | Content |
|---|---|
| `nodelodge://offers` | The machines bookable now, cheapest first |
| `nodelodge://sessions` | Your live sessions |
| `nodelodge://sessions/{session_id}` | One session, with its cost so far and SSH details |

And two **prompts**, ready-made requests that set the steps and the rules:

- `launch_cheapest_gpu` (`model`, `max_cost_usd`, optional `min_vram_gb`): estimates the VRAM the model needs and says it is an estimate, finds the cheapest machine with that much, checks your balance, asks you to confirm, then launches with your maximum and never raises it.
- `stop_all_sessions`: lists your live sessions, warns that stopping deletes each machine and its disk, asks you to confirm, stops them and checks that none is left.

In Claude Desktop and Claude Code, resources appear in the attachment menu (`@` in Claude Code) and prompts as slash commands, for example `/mcp__nodelodge__stop_all_sessions` in Claude Code.

## Worked example

You ask Claude Code:

> Find the cheapest GPU with at least 48 GB of VRAM, run my fine-tuning script on it within the budget I give you, and stop the machine when it is done. My public key is in ~/.ssh/id_ed25519.pub.

The agent then:

1. Calls `list_offers` with `min_vram_gb: 48` and picks the cheapest bookable offer, for example a 1× RTX A6000 in Montreal.
2. Calls `get_balance` and checks that your available credit covers the budget.
3. Asks you to confirm, then calls `launch_session`:

   ```json
   {
     "offer_id": "3f0c8f5e-8c3a-4f39-9a8e-2d9b4c1e7a10",
     "max_cost_usd": 20,
     "ssh_public_key": "ssh-ed25519 AAAAC3... you@laptop",
     "allowed_cidr": "203.0.113.7"
   }
   ```

   The `max_cost_usd` budget is reserved on your credit, and the machine starts provisioning.
4. Calls `get_session` until `connect` is set, then runs `ssh ubuntu@198.51.100.4`, copies the script, runs it and copies the results back.
5. Calls `stop_session`. The session is billed for the time it ran, and the rest of the budget is released.

If the agent had set `max_cost_usd` above the per-session limit of its key, Node Lodge would have refused the launch with `API_KEY_LIMIT`, and nothing would have been reserved or started.

## Errors the agent may see

| Code | Meaning |
|---|---|
| `CREDIT_INSUFFICIENT` | `max_cost_usd` is above your available credit. Add credit in **Billing**, or lower the maximum. |
| `API_KEY_LIMIT` | The budget would go past a limit of the key. Lower `max_cost_usd`, raise the limit in **Keys**, or wait for a session to end. |
| `MAX_COST_EXCEEDED` | The hours asked cost more than `max_cost_usd`. Shorten `duration_hours` or raise the maximum. |
| `API_KEY_NOT_ALLOWED` | The key lacks a scope the tool needs. Create a key with the three scopes above. |
| `OFFER_UNAVAILABLE` | The machine was taken in the meantime. Call `list_offers` again. |

## Good practice

- Give each agent its own key with tight limits, so you can revoke one without touching the others.
- Keep the key out of shared files and repositories. Claude Code stores it in your local configuration.
- Ask the agent to confirm before it launches a session or raises `max_cost_usd`.
- Every launch, budget raise and stop made with the key is listed in **Activity**, with the key that made it.
