Skip to main content
Glama
dam2452

vastai-mcp

by dam2452
README.md
# vastai-mcp

[Polski](README.pl.md)

Vast.ai GPU cloud marketplace and instance management MCP server.

Wraps the Vast.ai REST API (`https://console.vast.ai/api/v0`) so an LLM agent can search the GPU marketplace, rent machines, manage lifecycle, run commands, and inspect billing.

## Table of contents

- [Tools](#tools)
- [Environment variables](#environment-variables)
- [Wiring it up](#wiring-it-up)
- [Local run](#local-run)

## Tools

| Tool | Parameters | Description |
|------|------------|-------------|
| `search_offers` | `query: Dict[str, Any]` | Search the GPU marketplace (POST /bundles/) |
| `search_benchmarks` | `gpu_name: Optional[str] = None` | GPU benchmark data (GET /benchmarks/) |
| `search_templates` | `select_filters: Optional[Dict] = None` | Search user and public templates (GET /template/) |
| `get_gpu_metrics` | `gpu_name, verified, datacenter` | Current supply/demand/pricing snapshot |
| `get_gpu_trends` | `gpu_names, window_hours=24, step` | Historical price/supply time-series |
| `list_instances` | `label: Optional[str] = None` | List user's instances (GET /instances/) |
| `get_instance` | `instance_id: int` | Instance details (GET /instances/{id}/) |
| `create_instance` | `offer_id, image/template_hash_id, disk, runtype, env, onstart, price, ...` | Rent a GPU (PUT /asks/{offer_id}/) |
| `manage_instance` | `instance_id, action: Literal[...], label?` | start/stop/label/reboot/recycle |
| `destroy_instance` | `instance_id: int` | Permanently destroy (DELETE /instances/{id}/) |
| `change_bid` | `instance_id, price: float` | Change spot bid price |
| `show_instance_logs` | `instance_id, tail=1000` | Request instance logs |
| `execute_command` | `instance_id, command: str` | Run a remote command |
| `get_current_user` | none | Current account + credit balance |
| `raw_request` | `method, path, params?, body?` | Escape hatch for any other endpoint |
| `register_ssh_key` | `name, public_key_path` | Register a local public key on the Vast.ai account (POST /ssh/) |
| `list_ssh_keys` | none | List registered SSH keys (GET /ssh/) |
| `get_instance_ssh_info` | `instance_id` | Resolve `ssh_host`/`ssh_port` + ready-to-run `ssh` command |
| `ssh_exec` | `instance_id, command, key_path?, user="root", timeout=30` | Run a command over SSH (paramiko) |
| `ssh_transfer` | `direction: Literal["upload","download"], instance_id, local_path, remote_path, key_path?, user="root"` | SFTP upload/download between local disk and instance |

The `query` body for `search_offers` follows the Vast.ai filter operator convention: each field maps to `{eq, neq, gt, lt, gte, lte, in, notin}`. Example:

```json
{
  "gpu_name": {"in": ["RTX 4090"]},
  "num_gpus": {"gte": 1},
  "reliability": {"gte": 0.99},
  "verified": {"eq": true},
  "rentable": {"eq": true},
  "type": "ondemand",
  "limit": 5
}
```

## Environment variables

| Variable | Required | Description |
|----------|----------|-------------|
| `VASTAI_MCP_API_KEY` | yes | Vast.ai API key (https://cloud.vast.ai/manage-keys/) |
| `VASTAI_MCP_SSH_KEY_PATH` | no | Default path to your SSH **private** key, used by `ssh_exec` and `ssh_transfer` when `key_path` is not passed per-call |

## Wiring it up

Only requirement: `uv` (https://docs.astral.sh/uv/). Nothing else to install.

### Claude Code

```
claude mcp add vastai-mcp -e VASTAI_MCP_API_KEY=<value> -- uvx --from git+https://github.com/dam2452/vastai-mcp.git vastai-mcp
```

### Claude Desktop / other MCP client

```json
{
  "mcpServers": {
    "vastai-mcp": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/dam2452/vastai-mcp.git", "vastai-mcp"],
      "env": { "VASTAI_MCP_API_KEY": "<value>" }
    }
  }
}
```

After pushing a new version: `uv cache clean` and restart the client.

## Local run

```
uv run --directory . vastai-mcp
```

Tests (manual):

```
uv run --directory . --with pytest pytest test/
```

TDQS

A4.1/5.0

Scored across 20 tools

Disambiguation5/5

Each tool targets a distinct resource and action: search_offers/search_benchmarks/search_templates operate on different datasets, get_gpu_metrics vs get_gpu_trends differ by snapshot vs history, and instance tools are clearly separated (list/get/create/manage/destroy). Even potentially similar tools like execute_command and ssh_exec are explicitly differentiated by stopped vs running instance state.

Naming Consistency5/5

All tools follow a consistent verb_noun snake_case pattern (search_offers, list_instances, create_instance, destroy_instance, ssh_exec, ssh_transfer). The naming is predictable and consistent, with no camelCase or mixed conventions.

Tool Count4/5

20 tools is at the upper end of 'well-scoped' but appropriate for a full Vast.ai API surface covering marketplace search, instance CRUD, SSH operations, metrics, and user info. The count feels justified given the breadth of features, though slightly heavy compared to a typical 3-15 tool server.

Completeness4/5

The surface covers the main GPU rental workflow: search offers, create/read/delete instances, manage state, run commands, transfer files, and fetch metrics. Minor gaps like volume management exist, but the raw_request escape hatch covers any missing endpoint, preventing dead ends.

Maintenance

ActivityStale
ResponsivenessNo issues