Metadata-Version: 2.4
Name: massed-compute-mcp
Version: 1.0.2
Summary: MCP server for the Massed Compute API.
Project-URL: Homepage, https://github.com/Massed-Compute/massed-compute-mcp
Project-URL: Repository, https://github.com/Massed-Compute/massed-compute-mcp.git
Project-URL: Issues, https://github.com/Massed-Compute/massed-compute-mcp/issues
Project-URL: Documentation, https://vm-docs.massedcompute.com/docs/category/mcp
Author: Massed Compute
License: MIT
License-File: LICENSE
Keywords: ai,anthropic,claude,gpu,massed-compute,mcp,model-context-protocol,vm
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: mcp>=1.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# Massed Compute MCP Server

<!-- mcp-name: io.github.Massed-Compute/mcp -->

A [Model Context Protocol](https://modelcontextprotocol.io) server that lets AI assistants — Claude, Cursor, Codex, ChatGPT, and any other MCP-compatible client — interact with your [Massed Compute](https://vm.massedcompute.com) account on your behalf. Your AI client speaks the Model Context Protocol; our server translates.

## Features

- **14 tools** covering GPU inventory, instance lifecycle, SSH-key management, account billing, and coupons
- **Two install paths** — a local CLI (`npm install -g massed-compute-mcp`, or `pip install` once published) for power users and air-gapped setups, plus a hosted endpoint for zero-install convenience
- **Guided first-run setup** — `massed-compute-mcp init` prompts for your key, validates it against the upstream, and stores it in your OS config dir with restricted permissions
- **One-shot client wiring** — `massed-compute-mcp install-client claude-code` patches your MCP client config so you never hand-edit JSON
- **Granular access control** — issue a read-only key for analysis-only assistants; destructive tools return 403 and clients can hide them entirely
- **Works with every major MCP client** — Claude Code, Claude Desktop, Cursor, Codex

> 📚 Full documentation: [vm-docs.massedcompute.com/docs/category/mcp](https://vm-docs.massedcompute.com/docs/category/mcp)

## Example use cases

- **Fleet visibility** — ask what's currently running across regions, with hourly costs
- **Automated deployment** — have an assistant select GPU hardware, provision it, wait for boot, and hand back SSH access
- **Cost optimization** — get pricing recommendations grounded in live inventory data for workloads like fine-tuning LLMs

## Installation — local CLI (recommended)

The local CLI runs the MCP server on your machine and talks to `https://vm.massedcompute.com/api/v1/*` on your behalf. Your API key is stored in your OS config directory with file-mode `0600` (POSIX), never copied into the MCP client's config file, and never leaves your machine except as a Bearer token on requests to Massed Compute.

### 1. Get your API key

1. Go to [vm.massedcompute.com/settings/api](https://vm.massedcompute.com/settings/api).
2. Create a new API key.
   - **Read-only key:** for assistants that should only *observe* your account. Destructive tools (launch, restart, terminate, SSH-key changes) will return 403 if invoked.
   - **Full-access key:** for assistants that should be able to launch, restart, terminate, or manage SSH keys.
3. Copy the key.

### 2. Install the CLI

Pick whichever ecosystem you prefer — both ship the same binary name, same subcommands, same config-file location, and same env vars. You can switch between them without re-running `init`.

```bash
npm install -g massed-compute-mcp        # Node ≥ 20
# or
pip install massed-compute-mcp           # Python ≥ 3.10
# or
uv tool install massed-compute-mcp       # fast Python install via uv
```

### 3. Run setup — one command does everything

```bash
massed-compute-mcp init
```

That single command:

1. Prompts for your API key (input hidden) and validates it against the upstream.
2. Stores it at the platform-appropriate path:
   - **Linux:** `$XDG_CONFIG_HOME/massed-compute/config.json` (falls back to `~/.config/...`)
   - **macOS:** `~/Library/Application Support/massed-compute/config.json`
   - **Windows:** `%APPDATA%\massed-compute\config.json`
   - File written atomically with mode `0600` on POSIX.
3. Detects which MCP clients are installed on your machine (Claude Code, Cursor, Claude Desktop, Codex).
4. Offers to wire each detected client up — a timestamped backup is created before any edit.

Restart any wired MCP clients to pick up the new tools.

### Non-interactive setup (CI, scripts)

```bash
# Key from env var, auto-wire every detected client, no prompts
MASSED_COMPUTE_API_KEY=<your-key> massed-compute-mcp init --yes

# Or: key from a file, only wire specific clients
massed-compute-mcp init --token-file ~/keys/mc --yes --clients claude-code,cursor

# Or: just store the key, don't touch any client config
massed-compute-mcp init --yes --no-install-clients
```

### 4. Verify

```bash
massed-compute-mcp doctor
```

Confirms the stored key still works, prints the tool catalog, and shows copy-pasteable client snippets for any clients you didn't auto-wire.

### Add a client later

If you install another MCP client *after* running `init`, use:

```bash
massed-compute-mcp install-client cursor       # or claude-desktop, codex, claude-code
```

The command is idempotent — running it again when the entry already matches is a silent no-op (no backup file created).

To remove our entry from a client:

```bash
massed-compute-mcp uninstall-client cursor
```

### CLI commands

| Command | What it does |
|---|---|
| `massed-compute-mcp` *(no args)* | Run the MCP server over stdio (what MCP clients spawn) |
| `massed-compute-mcp init` | Interactive first-run setup: prompt, validate, store |
| `massed-compute-mcp doctor` | Verify the stored key and print client snippets |
| `massed-compute-mcp install-client <id>` | Patch a supported MCP client's config (`claude-code`, `cursor`, `claude-desktop`) |
| `massed-compute-mcp logout` | Delete the stored API key |
| `massed-compute-mcp tools [--json]` | Print the tool catalog (no upstream call) |
| `massed-compute-mcp version` | Print the version |
| `massed-compute-mcp help` | Show usage |

### Key resolution

When the server starts, the API key is taken from the first source that provides one:

1. `--token <value>` CLI flag (if passed to the server subcommand)
2. `MASSED_COMPUTE_API_KEY` environment variable
3. Stored config file written by `init`

If none of those are set, the server exits non-zero with a pointer to `massed-compute-mcp init`.

Override the upstream with `MASSED_COMPUTE_API_BASE_URL` (defaults to `https://vm.massedcompute.com`).

## Installation — hosted endpoint (no install)

If you don't want a local CLI on your machine, you can point your MCP client directly at the hosted endpoint. The same 14 tools are served from `https://vm.massedcompute.com/api/mcp` and authenticate with the same API key.

### Claude Code

```bash
claude mcp add --transport http massed-compute \
  https://vm.massedcompute.com/api/mcp \
  --header "Authorization: Bearer MC_TOKEN"
```

### Cursor — `~/.cursor/mcp.json`

```json
{
  "mcpServers": {
    "massed-compute": {
      "url": "https://vm.massedcompute.com/api/mcp",
      "headers": { "Authorization": "Bearer MC_TOKEN" }
    }
  }
}
```

### Codex — `~/.codex/config.toml`

```toml
[mcp_servers.massed-compute]
url = "https://vm.massedcompute.com/api/mcp"
bearer_token_env_var = "MC_TOKEN"
enabled = true
```

### Claude Desktop

Claude Desktop doesn't yet speak streamable-HTTP MCP, so use [`mcp-remote`](https://github.com/geelen/mcp-remote) as a stdio↔HTTP bridge. Config at `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "massed-compute": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://vm.massedcompute.com/api/mcp",
        "--header", "Authorization: Bearer MC_TOKEN"
      ]
    }
  }
}
```

### Verify

Ask your assistant *"Validate my Massed Compute API key."* If it returns `{ message: "Valid Token" }`, you're connected.

### When to choose which path

| Use the **local CLI** when… | Use the **hosted endpoint** when… |
|---|---|
| You want the API key kept off your MCP client's config file | You don't want to install anything |
| Your environment can't reach Massed Compute on every tool call (custom corporate proxy) — the CLI can be pointed at a relay | You use a client that doesn't support stdio (web-based assistants) |
| You want to fork and customize the wrapper | You want zero maintenance |
| You're scripting MCP calls outside of an MCP client | Edge-side rate limits matter (the hosted endpoint adds per-IP + per-user throttles) |

Both paths call the same documented `/api/v1/*` endpoints — there's no functional gap between them.

## How to choose a tool

Use this guide to pick the right tool for your task:

- **Want to know what GPUs you can rent?** Use `gpu_inventory_list`.
- **Want to know which OS / framework images are available?** Use `images_list`.
- **Want to know what's running right now?** Use `instances_list` (or `instances_get` if you have the UUID).
- **Want to launch a new VM?** Use `instances_launch`. *(Full-access key; incurs cost.)*
- **Want to reboot or kill an instance?** Use `instances_restart` or `instances_terminate`. *(Full-access key.)*
- **Want to check billing / token validity?** Use `account_billing` or `account_token_validation`.
- **Want to manage SSH keys?** Use `ssh_keys_list`, `ssh_keys_create`, or `ssh_keys_delete`.
- **Want to look up a coupon?** Use `coupon_information` for the discount terms, `coupon_accepted_products` for which products it applies to.

### Quick reference table

| Tool | Required key | Returns |
|---|---|---|
| `gpu_inventory_list` | read-only or full | GPU configurations, pricing, regional capacity |
| `images_list` | read-only or full | VM image catalog |
| `instances_list` | read-only or full | Your running VM instances |
| `instances_get` | read-only or full | A single instance by UUID |
| `instances_launch` | **full** | Newly-launched instance details *(incurs cost)* |
| `instances_restart` | **full** | Restart confirmation |
| `instances_terminate` | **full** | Termination confirmation *(destructive, permanent)* |
| `coupon_information` | read-only or full | Coupon discount terms |
| `coupon_accepted_products` | read-only or full | Products a coupon applies to |
| `account_token_validation` | read-only or full | Token validity status |
| `account_billing` | read-only or full | Billing settings, recharge config |
| `ssh_keys_list` | read-only or full | Your SSH keys |
| `ssh_keys_create` | **full** | Newly-created key details |
| `ssh_keys_delete` | **full** | Deletion confirmation *(destructive)* |

## Available tools

### 1. GPU Inventory (`gpu_inventory_list`)

Retrieve the catalog of GPU configurations available on Massed Compute, including specs, pricing, and current capacity by region.

**Best for:** choosing a GPU configuration for a workload; cost estimation; confirming what's in stock in a specific region.

**Arguments:** none.

**Prompt example:** *"What 1×L40 instances do you have, and where are they cheapest right now?"*

### 2. List VM Images (`images_list`)

Retrieve the catalog of preconfigured VM images available for deployment.

**Best for:** picking a base image for a new instance; understanding what's pre-installed.

**Arguments:** none.

**Prompt example:** *"Which images come with PyTorch and CUDA 12 already installed?"*

### 3. List Instances (`instances_list`)

Retrieve all running VM instances for the authenticated account. Sensitive credentials (e.g. cleartext VM password) are redacted in the response.

**Best for:** fleet visibility; "what am I paying for right now?"; pre-flight check before launching more.

**Arguments:** none.

**Prompt example:** *"List my running VMs with their hourly cost and uptime."*

### 4. Get Instance (`instances_get`)

Retrieve a single running VM instance by its UUID. Sensitive credentials are redacted in the response.

**Required argument:**
- `uuid` *(string)* — the instance UUID, e.g. as returned by `instances_list`.

**Prompt example:** *"Show me the IP and region for instance e7b1d28a-…"*

### 5. Launch Instance (`instances_launch`) — full-access key

Deploy a new VM instance. Requires billing to be configured (recharge amount and threshold). **This action incurs cost.**

**Required arguments:**
- `imageId` *(integer)* — ID of the VM image to deploy.
- `productName` *(string)* — product name of the GPU instance, e.g. `gpu_1x_l40`.
- `regionName` *(string)* — region name. Use `"any"` to let Massed Compute choose.

**Optional arguments:**
- `instanceName` *(string)*, `coupon` *(string)*, `command` *(string)*, `sshKeys` *(array of strings)*.

**Prompt example:** *"Launch a 1×L40 in the cheapest region using image 42, name it 'finetune-1', and attach my 'work-laptop' SSH key."*

### 6. Restart Instances (`instances_restart`) — full-access key

Restart one or more running VM instances by UUID. The VM is briefly unavailable during the reboot; disk data is preserved.

**Required argument:** `instanceUuids` *(array of strings)*.

### 7. Terminate Instances (`instances_terminate`) — full-access key

Terminate one or more running VM instances by UUID. **DESTRUCTIVE:** this stops billing for the listed instances and permanently deletes their data. The MCP `destructive` annotation will prompt your assistant to confirm before invoking.

**Required argument:** `instanceUuids` *(array of strings)*.

### 8. Coupon Information (`coupon_information`)

Look up the discount terms of a coupon by code.

**Required argument:** `coupon` *(string)*.

### 9. Coupon Accepted Products (`coupon_accepted_products`)

Look up which products a coupon code can be applied to, with current inventory availability.

**Required argument:** `coupon` *(string)*.

### 10. Validate API Token (`account_token_validation`)

Confirm that your Massed Compute API key is valid and active. Useful as a quick connectivity check.

**Arguments:** none.

### 11. Account Billing (`account_billing`)

Retrieve billing settings for the account, including billing method and recharge configuration.

**Arguments:** none.

### 12. List SSH Keys (`ssh_keys_list`)

List SSH keys associated with the authenticated account.

**Arguments:** none.

### 13. Add SSH Key (`ssh_keys_create`) — full-access key

Add a new SSH public key to the authenticated account.

**Required arguments:** `name` *(string)*, `publicKey` *(string, OpenSSH format)*.

### 14. Delete SSH Key (`ssh_keys_delete`) — full-access key

Remove an SSH key from the account. **DESTRUCTIVE:** any instances relying on this key may lose access.

**Required argument:** `sshKeyId` *(string)* — UUID of the SSH key to remove, as returned by `ssh_keys_list`.

## Agent Skills

Beyond raw tools, Massed Compute publishes **Agent Skills** — markdown workflow templates that turn the underlying tools into practical operations like GPU selection and cost auditing. See the [Agent Skills documentation](https://vm-docs.massedcompute.com/docs/mcp/skills).

## Troubleshooting

For diagnostic guidance on common issues, run `massed-compute-mcp doctor` first — it'll tell you whether the key is reachable, valid, and which client snippets to paste. For deeper guidance, see the [Troubleshooting docs](https://vm-docs.massedcompute.com/docs/mcp/troubleshooting).

## Security

- The local CLI stores your API key in your OS config dir with mode `0600` (POSIX). On Windows the file inherits user-profile ACLs.
- The MCP server holds no credentials beyond what you give it and stores no per-call state. Your API key is forwarded as a Bearer header to `https://vm.massedcompute.com/api/v1/*` on each tool call.
- The wrapper never calls undocumented endpoints or internal services. The 14 tools map 1:1 to documented public API operations.
- **Best practice:** generate a separate read-only key for any assistant that doesn't need to make changes. Destructive tools then return 403 instead of executing.

## Repo layout

This repository is a monorepo containing the wrapper in multiple languages, all driven from a shared tool spec:

```
massed-compute-mcp/
├── tools.json              # single source of truth — 14 tool definitions
├── packages/
│   ├── node/               # npm package: massed-compute-mcp (TypeScript)
│   └── python/             # pip package: massed-compute-mcp (Python ≥ 3.10)
└── scripts/
    ├── sync-tools.mjs      # copies tools.json + README + LICENSE into each package
    └── contract-test.mjs   # asserts every package + the hosted endpoint agree
```

The Node and Python packages ship identical UX — same subcommands, same env vars, same on-disk config schema. The contract test runs in CI and fails loudly if the two implementations or the hosted endpoint drift.

## Resources

- [Full MCP documentation](https://vm-docs.massedcompute.com/docs/category/mcp)
- [Massed Compute API reference](https://vm-docs.massedcompute.com/api/v1)
- [Massed Compute console](https://vm.massedcompute.com)
- [Model Context Protocol spec](https://modelcontextprotocol.io)

## License

MIT — see [LICENSE](./LICENSE).
