Orgo MCP Server
# Orgo MCP Server
Official MCP server for controlling [Orgo](https://orgo.ai) cloud computers from Claude Code, Claude Desktop, and other Model Context Protocol clients.
**Install from GitHub, not npm.** The canonical install is `npx -y github:nickvasilescu/orgo-mcp` — the repo ships prebuilt `dist/`, so this is a fast registry-style install (no compile step). The npm registry still has the obsolete 3.0.0; do **not** use `npx @orgo-ai/mcp` until a 4.x release lands there.
## Quick Start
### 1. Get an Orgo API key
Sign up or log in at [orgo.ai](https://orgo.ai), then copy an API key from **Settings > API Keys**.
### 2. Add the MCP server
The install path uses the GitHub URL so you get the current 4.x build (compact mode, limit, `orgo_doctor`, etc.). Pin to a release tag for production stability; omit the `#ref` to track the `main` branch.
Claude Code:
```bash
# Latest from main (prebuilt — installs in seconds)
claude mcp add orgo -e ORGO_API_KEY=sk_live_YOUR_KEY -- npx -y github:nickvasilescu/orgo-mcp
# Or pin to a release tag
claude mcp add orgo -e ORGO_API_KEY=sk_live_YOUR_KEY -- npx -y github:nickvasilescu/orgo-mcp#v4.1.1
```
Claude Desktop:
```json
{
"mcpServers": {
"orgo": {
"command": "npx",
"args": ["-y", "github:nickvasilescu/orgo-mcp"],
"env": {
"ORGO_API_KEY": "sk_live_YOUR_KEY"
}
}
}
}
```
Hosted Streamable HTTP server (Claude Code, Cursor, VS Code, and other clients
that support remote MCP over HTTP):
```json
{
"mcpServers": {
"orgo": {
"type": "http",
"url": "https://orgo-mcp.onrender.com/mcp",
"headers": {
"X-Orgo-API-Key": "${ORGO_API_KEY}",
"X-Orgo-Default-Computer-Id": "your-computer-id"
}
}
}
}
```
The exact shape varies by client: **Cursor** omits `type` (it infers the
transport from `url`), **Windsurf** names the field `serverUrl`, and **VS Code**
nests servers under a `servers` key instead of `mcpServers`.
**Claude Desktop is the exception** — `claude_desktop_config.json` is stdio-only
and will not start a `type: http` entry. To reach the hosted endpoint from
Claude Desktop, bridge it with [`mcp-remote`](https://github.com/geelen/mcp-remote)
(still a stdio command under `mcpServers`):
```json
{
"mcpServers": {
"orgo": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://orgo-mcp.onrender.com/mcp",
"--transport", "http-only",
"--header", "X-Orgo-API-Key:${ORGO_API_KEY}",
"--header", "X-Orgo-Default-Computer-Id:${ORGO_DEFAULT_COMPUTER_ID}"
],
"env": {
"ORGO_API_KEY": "sk_live_YOUR_KEY",
"ORGO_DEFAULT_COMPUTER_ID": "your-computer-id"
}
}
}
}
```
`X-Orgo-Default-Computer-Id` is optional: it pins a default computer for this
connection so tool calls can omit `computer_id` (the remote equivalent of the
`ORGO_DEFAULT_COMPUTER_ID` env var, which can't be per-user on a shared host).
Clients that only let you configure a URL can pass it as a query param instead:
`https://orgo-mcp.onrender.com/mcp?computer_id=your-computer-id`.
PowerShell users can wrap the Claude Code command because PowerShell may mangle `--` when it reaches npm shims:
```powershell
cmd /c "claude mcp add orgo -e ORGO_API_KEY=sk_live_YOUR_KEY -- npx -y github:nickvasilescu/orgo-mcp"
```
> **About the GitHub install.** The repo commits prebuilt `dist/` and has no `prepare` script, so `npx` fetches the repo and installs only the three runtime dependencies — no TypeScript toolchain, no compile. Cold installs take a few seconds; subsequent invocations are cached. CI rejects any commit whose `dist/` doesn't match `src/`, so `main` is always runnable.
## Tools
The server exposes 28 focused tools.
| Toolset | Tools |
| --- | --- |
| `core` | `orgo_list_workspaces`, `orgo_get_workspace`, `orgo_workspace_by_name`, `orgo_list_computers`, `orgo_get_computer`, `orgo_doctor` |
| `admin` | `orgo_create_workspace`, `orgo_delete_workspace`, `orgo_create_computer`, `orgo_delete_computer`, `orgo_restart_computer`, `orgo_clone_computer`, `orgo_ensure_running`, `orgo_resize_computer`, `orgo_move_computer` |
| `screen` | `orgo_screenshot`, `orgo_click`, `orgo_type`, `orgo_key`, `orgo_scroll`, `orgo_drag`, `orgo_wait` |
| `shell` | `orgo_bash`, `orgo_exec` |
| `files` | `orgo_list_files`, `orgo_export_file`, `orgo_upload_file`, `orgo_download_file` |
Each tool is registered with MCP annotations for `readOnlyHint`, `destructiveHint`, `idempotentHint`, and `openWorldHint`.
`orgo_restart_computer` is marked destructive because it can interrupt running processes and unsaved VM state.
Text responses are sanitized before they are returned to the MCP client, so password, token, secret, credential, and API-key fields are redacted even when Orgo API responses include them.
### Compact mode for read tools
Read tools (`orgo_list_workspaces`, `orgo_get_workspace`, `orgo_workspace_by_name`, `orgo_list_computers`, `orgo_get_computer`, `orgo_list_files`) are **compact by default since 4.1.0**: noisy fields like `instance_details`, `template_build_id`, and `user_id` are dropped, keeping `id`, `name`, `status`, timestamps, and key resource fields (`cpu`, `ram`, `os`, `disk_size_gb`, `fly_instance_id`, file `size`/`path`). Typical savings: 50%+ on list endpoints (a 290 KB workspace list shrinks to ~50 KB). Pass `compact: false` when you need the complete raw payload. Responses are also no longer pretty-printed — both changes affect default response shape if you upgraded from ≤4.0.x.
### Health check (`orgo_doctor`)
Call `orgo_doctor` (no arguments) to probe MCP server health: auth source detected (`env:ORGO_API_KEY` or `http_header`, never the key value), API reachability with status code, and round-trip latency in ms. Returns `{ ok, auth, api }` — `ok: true` means both auth is configured and the live Orgo API responded. Use as the first call from an agent harness to verify setup, or after a tool error to distinguish auth failures (`status_code: 401`) from network issues (no status_code, `error: "Cannot reach Orgo API"`).
### Client-side limit for list tools
Pass `limit: N` (1–500) to `orgo_list_workspaces`, `orgo_list_computers`, or `orgo_list_files` to cap the number of items returned. The Orgo API does not paginate server-side, so the MCP fetches everything and trims client-side. When truncation occurs, the response gains `total` (the real count) and `truncated: true`. Omit `limit` to return everything (current default — backward compatible). Combine with `compact: true` for the smallest payload: `{ limit: 5, compact: true }` typically returns under 3KB even on accounts with hundreds of computers.
Deliberately not exposed:
- computer start/stop tools
- VNC password access
- account/profile/credits/transactions
- autonomous agent/thread tools
- RTMP streaming tools
- template management tools
## Production Safety Controls
Use environment variables to restrict the exposed surface without changing client config.
| Variable | Default | Description |
| --- | --- | --- |
| `ORGO_READ_ONLY` | `false` | When `true`, only tools annotated as read-only are registered. |
| `ORGO_TOOLSETS` | `core,admin,screen,shell,files` | Comma-separated toolsets to expose. Example: `core,screen,files`. |
| `ORGO_ENABLED_TOOLS` | all registered tools | Exact comma-separated allowlist. Applied before `ORGO_DISABLED_TOOLS`. |
| `ORGO_DISABLED_TOOLS` | none | Exact comma-separated denylist. |
Examples:
```bash
# Observation-only mode
ORGO_READ_ONLY=true npx -y github:nickvasilescu/orgo-mcp
# Browserless VM control without shell access
ORGO_TOOLSETS=core,screen,files npx -y github:nickvasilescu/orgo-mcp
# Keep shell enabled, but remove bash
ORGO_TOOLSETS=shell ORGO_DISABLED_TOOLS=orgo_bash npx -y github:nickvasilescu/orgo-mcp
```
Read-only mode currently exposes:
```text
orgo_list_workspaces
orgo_get_workspace
orgo_workspace_by_name
orgo_list_computers
orgo_get_computer
orgo_screenshot
orgo_wait
orgo_list_files
orgo_download_file
orgo_doctor
```
## Environment Variables
| Variable | Default | Description |
| --- | --- | --- |
| `ORGO_API_KEY` | none | Required for stdio transport. HTTP deployments receive user keys via `X-Orgo-API-Key`. |
| `ORGO_DEFAULT_COMPUTER_ID` | none | Default computer ID so tool calls can omit `computer_id` (stdio). For HTTP, send a per-request `X-Orgo-Default-Computer-Id` header (or `?computer_id=`) instead. |
| `MCP_TRANSPORT` | `stdio` | `stdio`, `http`, or `streamable-http`. |
| `MCP_HOST` | `0.0.0.0` | HTTP bind address. |
| `MCP_PORT` / `PORT` | `8000` | HTTP port. |
## Self-Hosting
Local stdio:
```bash
git clone https://github.com/nickvasilescu/orgo-mcp.git
cd orgo-mcp
npm install
ORGO_API_KEY=sk_live_YOUR_KEY npm start
```
Local HTTP:
```bash
npm install
npm run build
MCP_TRANSPORT=http npm start
curl http://localhost:8000/health
```
Docker:
```bash
docker build -t orgo-mcp .
docker run -p 8000:8000 -e MCP_TRANSPORT=http orgo-mcp
```
Render:
1. Fork this repo.
2. Create a Render Blueprint from `render.yaml`.
3. Connect clients to `https://YOUR_RENDER_HOST/mcp` with an `X-Orgo-API-Key` header.
The hosted server does not store a shared Orgo key. Each request must include the user's Orgo API key header.
## Architecture
```text
npx / stdio:
MCP client -> stdio -> @orgo-ai/mcp -> Orgo API
ORGO_API_KEY env var
Hosted HTTP:
MCP client -> HTTPS -> orgo-mcp server -> Orgo API
X-Orgo-API-Key header
Shell commands:
orgo_bash -> Terminal WebSocket primary -> VM
-> REST /bash fallback -> VM
```
## Development
```bash
npm install
npm run build
npm test
npm start
```
CI runs:
- TypeScript build from a clean `dist/`
- MCP tool-list smoke tests for default, read-only, toolset, allowlist, and denylist policies
- HTTP transport health and auth smoke tests
- committed-`dist/` freshness check (rebuild must produce no diff)
- npm package content checks
- Docker image build
`dist/` is committed so the GitHub install needs no build step — after changing `src/`, run `npm run build` and commit the regenerated `dist/` alongside.
Before publishing:
```bash
npm test
npm pack --dry-run
```
## Troubleshooting
| Error | Fix |
| --- | --- |
| `Invalid API key` | Check the Orgo API key and whether it is active. |
| `X-Orgo-API-Key header required` | HTTP clients must send this header on `/mcp` requests. |
| `computer_id required` | Pass `computer_id`, set `ORGO_DEFAULT_COMPUTER_ID` (stdio), or send `X-Orgo-Default-Computer-Id` / `?computer_id=` (HTTP). |
| `Connection refused` | Confirm the server is running and check `/health`. |
| Tools not appearing | Check `ORGO_READ_ONLY`, `ORGO_TOOLSETS`, `ORGO_ENABLED_TOOLS`, and `ORGO_DISABLED_TOOLS`. |
## Security
- Do not commit `.env` files or API keys.
- Prefer `ORGO_READ_ONLY=true` for observation-only clients.
- Disable the `shell` toolset for clients that should not execute VM commands.
- Treat `orgo_bash` and `orgo_exec` as high-power tools: they can modify anything reachable from the target VM.
- HTTP deployments should pass the user's key per request via `X-Orgo-API-Key`; do not bake a production Orgo key into the server.
## License
MIT. See [LICENSE](LICENSE).
TDQS
Scored across 35 tools
Most tools have clearly distinct purposes, but some overlap exists (e.g., orgo_bash vs orgo_exec, orgo_download_file vs orgo_export_file). Descriptions are detailed enough to resolve confusion, but the large number of tools still requires careful reading.
All tools follow a consistent orgo_verb_noun pattern using snake_case (e.g., orgo_create_computer, orgo_list_projects). The naming is predictable and uniform across the entire set.
35 tools is significantly above the typical 3-15 range, but the broad domain (project/computer management, file operations, AI, streaming) justifies most tools. However, some tools could be consolidated (e.g., start/stop/restart per resource).
The tool surface covers CRUD for projects/computers, file operations, AI completions, streaming, and system interaction. Missing are update operations (e.g., update_computer, update_project) and possibly batch file actions, but core workflows are well-supported.