Content
# LetsCloud MCP Server
> 🇧🇷 [Versão em português](README_PT.md)
> **Remote MCP server + REST API to manage [LetsCloud](https://www.letscloud.io) infrastructure with AI assistants.**
This project exposes LetsCloud's cloud platform through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io) so AI assistants like **Claude**, **Cursor**, **Windsurf**, **VS Code Copilot**, and any MCP-compatible client can create and manage servers, snapshots and SSH keys on behalf of the user.
Unlike "local" MCP servers, **this is a hosted service**: any LetsCloud customer can connect by providing their API key — **no installation required on the client side**.
The same backend also exposes a clean **REST API** under `/api/v1` for plain HTTP integrations (curl, scripts, automations).
---
## ✨ Features
- 🔌 **Native MCP transport** (Streamable HTTP) at `/mcp`
- 🌐 **REST API** at `/api/v1` mirroring every MCP tool
- 🔑 **Per-request authentication** via `Authorization: Bearer <api-key>`
- 📦 Full coverage of the LetsCloud API — instances, SSH keys, snapshots, plans, images, locations, account
- ⚡ Async, fast and lightweight (FastAPI + httpx + official MCP SDK)
- 🐳 Docker-ready
- 📝 Auto-generated OpenAPI docs at `/docs`
---
## 🧠 How it works
```
┌──────────────────┐ Authorization: Bearer <api-key> ┌──────────────────────┐
│ AI client (MCP) │ ───────────────────────────────────────► │ mcp.letscloud.io/mcp │
│ Claude, Cursor… │ │ (this server) │
└──────────────────┘ └──────────┬───────────┘
│ api-token: <key>
▼
┌──────────────────────────┐
│ core.letscloud.io/api │
└──────────────────────────┘
```
The user's API key never leaves the request: the server just relays it to the LetsCloud upstream and returns the response. The server itself stores no credentials.
---
## 🚀 Quick start (using the hosted server)
### Get your API key
Generate an API key in the [LetsCloud dashboard](https://my.letscloud.io).
### Configure your MCP client
#### Claude Desktop / Cursor / Windsurf (remote MCP)
```json
{
"mcpServers": {
"letscloud": {
"url": "https://mcp.letscloud.io/mcp",
"headers": {
"Authorization": "Bearer YOUR_LETSCLOUD_API_KEY"
}
}
}
}
```
> **Note**: the exact field names may differ slightly between clients (some use `transport: "streamable-http"`, others auto-detect). Check your client's docs for "remote MCP server".
#### Test from curl (REST API)
```bash
curl -H "Authorization: Bearer YOUR_LETSCLOUD_API_KEY" \
https://mcp.letscloud.io/api/v1/account
```
```bash
curl -H "Authorization: Bearer YOUR_LETSCLOUD_API_KEY" \
https://mcp.letscloud.io/api/v1/instances
```
---
## 🛠️ Available tools
| MCP tool | REST endpoint | Description |
|---|---|---|
| `get_account_info` | `GET /api/v1/account` | Account profile (name, balance, email…) |
| `list_locations` | `GET /api/v1/locations` | All datacenter locations |
| `list_plans` | `GET /api/v1/locations/{slug}/plans` | Plans available at a location |
| `list_images` | `GET /api/v1/locations/{slug}/images` | OS images at a location |
| `list_ssh_keys` | `GET /api/v1/ssh-keys` | List SSH keys |
| `get_ssh_key` | `GET /api/v1/ssh-keys/{title}` | Get one SSH key |
| `create_ssh_key` | `POST /api/v1/ssh-keys` | Create SSH key |
| `delete_ssh_key` | `DELETE /api/v1/ssh-keys/{slug}` | Delete SSH key |
| `list_servers` | `GET /api/v1/instances` | List instances |
| `get_server` | `GET /api/v1/instances/{id}` | Instance details |
| `create_server` | `POST /api/v1/instances` | Create instance |
| `delete_server` | `DELETE /api/v1/instances/{id}` | Delete instance |
| `start_server` | `PUT /api/v1/instances/{id}/power-on` | Power on |
| `shutdown_server` | `PUT /api/v1/instances/{id}/power-off` | Power off |
| `reboot_server` | `PUT /api/v1/instances/{id}/reboot` | Reboot |
| `reset_server_password` | `PUT /api/v1/instances/{id}/reset-password` | Reset root password |
| `list_snapshots` | `GET /api/v1/snapshots` | List snapshots |
| `get_snapshot` | `GET /api/v1/snapshots/{slug}` | Snapshot details |
| `create_snapshot` | `POST /api/v1/instances/{id}/snapshots` | Create snapshot |
| `update_snapshot` | `PUT /api/v1/snapshots/{slug}` | Rename snapshot |
| `delete_snapshot` | `DELETE /api/v1/snapshots/{slug}` | Delete snapshot |
Full interactive docs (with request/response schemas) are available at `/docs`.
---
## 📡 Hosted vs self-hosted
This project ships as a **hosted service** at <https://mcp.letscloud.io>,
operated by the LetsCloud team. As an end user you only need your
LetsCloud API key — there is **nothing to install locally**.
If you want to run your **own private instance** (corporate VPC, offline
tests, contributions), see [DEPLOY.md](DEPLOY.md) for a one-command Docker
or Python setup.
---
## 🔐 Authentication
Every request to `/mcp` and `/api/v1/*` must carry the user's LetsCloud API key in **one** of:
- `Authorization: Bearer <api-key>` (recommended, MCP-friendly)
- `X-LetsCloud-Token: <api-key>` (fallback)
The server forwards the key to LetsCloud's API as `api-token: <key>` (matching the [official Go SDK](https://github.com/letscloud-community/letscloud-go) behavior). **The server stores nothing.**
---
## 🏗️ Architecture
```
src/letscloud_mcp/
├── main.py # FastAPI app, mounts /mcp and /api/v1
├── __main__.py # uvicorn entrypoint (python -m letscloud_mcp)
├── config.py # Settings via pydantic-settings
├── auth.py # Per-request token extraction (ContextVar)
├── logging_setup.py # structlog
├── letscloud/
│ ├── client.py # Async httpx client for core.letscloud.io
│ ├── models.py # Pydantic models (Profile, Instance, Snapshot…)
│ └── exceptions.py
├── mcp_app/
│ ├── server.py # FastMCP server (Streamable HTTP)
│ └── tools.py # @mcp.tool functions
└── rest/
└── routes.py # FastAPI router for /api/v1
```
---
## 📄 License
MIT — see [LICENSE](LICENSE).
## 🔗 Links
- [LetsCloud](https://www.letscloud.io) – cloud provider
- [Official Go SDK](https://github.com/letscloud-community/letscloud-go) – the basis for this client
- [Model Context Protocol](https://modelcontextprotocol.io)
- [Self-hosting guide](DEPLOY.md)
- [Security policy](SECURITY.md) · [Contributing](CONTRIBUTING.md)
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.