npm package: @selfhost.dev/mcp-server
Description: MCP server for SelfHost.dev — Manage Database Infrastructure via Natural Language
Latest version: 0.1.1

# SelfHost MCP Server

A full-featured [Model Context Protocol](https://modelcontextprotocol.io/) server that brings [SelfHost's](https://selfhost.dev) database management capabilities directly into AI coding assistants. Provision, monitor, scale, and manage production database infrastructure — all through natural language, without leaving your editor.

Works with **Claude Code**, **Cursor**, **Windsurf**, **Cline**, and any MCP-compatible client.

---

## Quick Start

### Prerequisites

- A [SelfHost.dev](https://selfhost.dev) account (invite-only — ask an existing user or join the waitlist)
- **Node.js 18+** or **Bun**

### Install

**Claude Code:**

```bash
# Using npm (Node.js)
claude mcp add selfhost -- npx @selfhost.dev/mcp-server

# Using Bun
claude mcp add selfhost -- bunx @selfhost.dev/mcp-server
```

**Cursor / Windsurf / Other MCP clients:**

Add to your MCP configuration file:

```json
{
  "mcpServers": {
    "selfhost": {
      "command": "npx",
      "args": ["@selfhost.dev/mcp-server"]
    }
  }
}
```

Or with Bun:

```json
{
  "mcpServers": {
    "selfhost": {
      "command": "bunx",
      "args": ["@selfhost.dev/mcp-server"]
    }
  }
}
```

That's it. The server handles authentication, token refresh, and everything else automatically.

### First Run

On first use, the MCP server opens your browser to sign in via SelfHost's console. After you authorize, credentials are saved locally (`~/.selfhost/credentials.json`) and auto-refreshed — you won't need to sign in again.

```
You: "Show me my databases"

Claude: Authenticates → fetches your orgs → selects org → lists instances
        → Shows you a summary of all your running databases
```

---

## What Can You Do?

### Talk to your infrastructure in plain English

| You say | What happens |
|---------|-------------|
| *"Spin up a Postgres 18 instance in us-east-1"* | Walks you through config, shows cost estimate, provisions it |
| *"Stop my staging database"* | Finds the instance, confirms with you, stops it |
| *"Set up a CPU alert at 80% on my prod DB"* | Creates an alert rule with email notification |
| *"Show me the backups for my main instance"* | Lists all backups with sizes and timestamps |
| *"Fork my production database for testing"* | Creates an independent clone with a new password |
| *"What's my estimated monthly cost for an r6i.xlarge with 500GB gp3?"* | Calculates itemized cost breakdown |
| *"Tune shared_buffers on my instance"* | Previews defaults, applies the override, syncs to replicas |

### Safety Built In

Destructive operations (delete, stop, reboot) require explicit confirmation. The server will always ask before proceeding — you'll never accidentally delete a production database.

---

## Features

### 76 tools across 8 modules

Every tool maps to a real API endpoint. No mock data, no shortcuts.

#### Authentication & Users
Automatic browser-based sign-in with Firebase. Tokens refresh transparently.

| Tool | Description |
|------|-------------|
| `create_or_login_user` | Create account or sign in |
| `get_current_user` | Your profile, admin status, org membership |
| `get_my_memberships` | List your orgs and pending invitations |
| `select_organization` | Switch org context (sets rate limits based on billing plan) |
| `get_invite_credits` | Check remaining platform invite credits |
| `send_platform_invite` | Invite someone to join SelfHost |
| `list_my_platform_invites` | See invitations you've sent |
| `reauthenticate` | Sign out and sign in again (switch accounts) |

#### Organizations & Team Management
Multi-tenant — everything is scoped to your org.

| Tool | Description |
|------|-------------|
| `list_organizations` | All orgs you belong to |
| `create_organization` | Create a new org (you become owner, get 5 invite credits) |
| `get_organization` | Org details and billing plan |
| `update_organization` | Change name, description, or IAM role |
| `delete_organization` | Soft-delete org and all related resources |
| `list_members` | See team members and their roles |
| `remove_member` | Remove a member (owner/admin only) |
| `invite_to_org` | Send org invitation with role assignment |
| `list_org_invitations` | Pending invitations |
| `cancel_invitation` | Revoke a pending invitation |
| `get_my_invitations` | Invitations sent to you |
| `list_activity_logs` | Audit trail of all actions in the org |

#### Cloud Credentials
Bring your own AWS account (BYOC) or use SelfHost's managed infrastructure.

| Tool | Description |
|------|-------------|
| `list_credentials` | List cloud credentials (secrets never exposed) |
| `add_credential` | Add AWS access keys or IAM role |
| `update_credential` | Rotate keys or update metadata |
| `delete_credential` | Remove a credential (with confirmation) |
| `set_default_credential` | Set as default for the org |
| `get_aws_account_info` | AWS account ID and free tier status |

#### Networking
VPCs, subnets, and security groups. Optional — auto-created during provisioning if not specified.

| Tool | Description |
|------|-------------|
| `list_vpcs` | List VPCs in a region (grouped by public/private) |
| `create_vpc` | Create VPC with internet gateway and subnets |
| `delete_vpc` | Remove VPC and associated resources (with confirmation) |
| `list_subnets` | List subnets in a region |
| `create_subnet` | Create subnet in a VPC |
| `list_security_groups` | List security groups |
| `create_security_group` | Create SG with inbound rules |
| `update_security_group` | Replace inbound rules on a security group |

#### Database Instances
The core feature. Full lifecycle management for PostgreSQL, MySQL, and MongoDB.

| Tool | Description |
|------|-------------|
| `list_regions` | Available AWS regions |
| `get_instance_types_for_region` | EC2 types with specs and hourly pricing |
| `list_storage_types` | EBS volume types with pricing |
| `estimate_instance_cost` | Itemized monthly cost breakdown before provisioning |
| `create_instance` | Provision a new database (guided flow with cost confirmation) |
| `list_instances` | All instances grouped by master + replicas |
| `get_instance` | Detailed instance info with latest metrics |
| `update_instance` | Change config, resize, toggle multi-AZ, update CIDR ranges |
| `stop_instance` | Stop instances (with confirmation) |
| `start_instance` | Start stopped instances |
| `reboot_instance` | Reboot instances (with confirmation) |
| `delete_instance` | Delete instances with optional final snapshot (with confirmation) |
| `fork_instance` | Clone a database into a new independent instance |
| `refresh_instance_group` | Refresh cached state for a master + replica group |

#### PostgreSQL Configuration
Tune database parameters with calculated defaults per instance type.

| Tool | Description |
|------|-------------|
| `preview_pg_config` | See calculated defaults for an instance type (before creating) |
| `get_pg_config` | Current config with defaults, overrides, and effective values |
| `update_pg_config` | Apply overrides (auto-syncs to replicas, set null to revert) |

#### Backups & Snapshots
Automated backups with DLM policies and manual EBS snapshots.

| Tool | Description |
|------|-------------|
| `list_backups` | List all backups (syncs with AWS) |
| `create_backup` | Create S3 file backup or AWS backup job |
| `delete_backup` | Delete backup and AWS snapshot (with confirmation) |
| `list_backup_policies` | List DLM lifecycle policies |
| `create_backup_policy` | Create automated backup schedule |
| `update_backup_policy` | Enable/disable or modify schedule |
| `delete_backup_policy` | Remove policy (with confirmation) |
| `list_snapshots` | List EBS snapshots in a region |
| `get_snapshot` | Snapshot details |
| `delete_snapshot` | Delete EBS snapshot (with confirmation) |
| `create_snapshot` | Create EBS snapshot from instance volume |

#### Alerts & Notifications
Monitor your databases and get notified when things go wrong.

| Tool | Description |
|------|-------------|
| `list_alert_rules` | Active alert rules |
| `create_alert_rule` | Create rule (CPU, memory, disk, replication lag, etc.) |
| `get_alert_rule` | Rule details |
| `update_alert_rule` | Modify thresholds or notification channels |
| `delete_alert_rule` | Delete rule and all instances (with confirmation) |
| `list_alert_instances` | Fired/pending/resolved alerts (paginated) |
| `get_alert_instance` | Alert instance details |
| `acknowledge_alert` | Acknowledge a firing alert |
| `resolve_alert` | Manually resolve an alert |
| `list_notification_channels` | Email notification endpoints |
| `create_notification_channel` | Add email channel |
| `update_notification_channel` | Modify channel config |
| `delete_notification_channel` | Remove channel (with confirmation) |
| `test_notification_channel` | Send test notification |

---

## Common Workflows

### Switch AWS Account (BYOC vs Platform-Managed)

```
You: "I want to use my own AWS account"

Claude: Lists your credentials → you pick one (or add new keys)
        → fetches VPCs in your chosen region → you pick a VPC
        → proceeds with instance creation using your account
```

### Switch Organization

If you belong to multiple orgs:

```
You: "Switch to my other org"

Claude: Calls get_my_memberships → shows your orgs
        → you pick one → calls select_organization
        → rate limits and context update to the new org
```

### Re-authenticate (Switch Accounts)

If you need to sign in as a different user:

```
You: "Sign in with a different account"

Claude: Calls reauthenticate → clears stored credentials
        → opens browser for new login → saves new tokens
        → you're now signed in as the other user
```

### Restore from Backup

```
You: "Restore my prod database from yesterday's snapshot"

Claude: Lists snapshots → you pick one
        → creates a new instance with snapshot_id
        → shows you the new password (save it!)
```

---

## Rate Limiting

Rate limits are based on your org's billing plan and enforced per-user:

| Plan | Reads/min | Writes/min | Concurrent |
|------|-----------|------------|------------|
| Free | ~60 | ~20 | 3 |
| Starter | ~150 | ~50 | 5 |
| Pro | ~300 | ~120 | 10 |
| Enterprise | ~600 | ~300 | Unlimited |

Reference data lookups (regions, instance types, storage types) are unlimited.

---

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `API_URL` | `https://api.selfhost.dev` | SelfHost API endpoint |
| `CONSOLE_URL` | `https://console.selfhost.dev` | SelfHost Console URL (for browser auth) |
| `TIER` | Auto-detected | Override rate limit tier (`FREE`, `STARTER`, `PRO`, `ENTERPRISE`, `ADMIN`) |
| `FIREBASE_API_KEY` | — | Skip browser auth (CI/headless) |
| `FIREBASE_REFRESH_TOKEN` | — | Skip browser auth (CI/headless) |

### Local Development

Both `API_URL` and `CONSOLE_URL` are optional overrides — they default to the production endpoints when not set.

**1. Local Rails API + Local Console**

Using npx:
```json
{
  "mcpServers": {
    "selfhost": {
      "command": "npx",
      "args": ["tsx", "/path/to/selfhost-mcp/src/index.ts"],
      "env": {
        "API_URL": "http://localhost:3000",
        "CONSOLE_URL": "http://localhost:54588"
      }
    }
  }
}
```

Using bun:
```json
{
  "mcpServers": {
    "selfhost": {
      "command": "bun",
      "args": ["run", "/path/to/selfhost-mcp/src/index.ts"],
      "env": {
        "API_URL": "http://localhost:3000",
        "CONSOLE_URL": "http://localhost:54588"
      }
    }
  }
}
```

**2. Local Rails API + Production Console**

```json
{
  "mcpServers": {
    "selfhost": {
      "command": "npx",
      "args": ["tsx", "/path/to/selfhost-mcp/src/index.ts"],
      "env": {
        "API_URL": "http://localhost:3000"
      }
    }
  }
}
```

**3. Production Rails API + Local Console**

```json
{
  "mcpServers": {
    "selfhost": {
      "command": "npx",
      "args": ["tsx", "/path/to/selfhost-mcp/src/index.ts"],
      "env": {
        "CONSOLE_URL": "http://localhost:54588"
      }
    }
  }
}
```

### Headless / CI Mode

Set `FIREBASE_API_KEY` and `FIREBASE_REFRESH_TOKEN` environment variables to skip the browser login flow. You can find these values in `~/.selfhost/credentials.json` after your first browser login.

---

## Security

- **Credentials stored locally** at `~/.selfhost/credentials.json` with `chmod 0600` (owner-only read/write)
- **JWT auto-refresh** — tokens refresh 5 minutes before expiry, refresh tokens are rotated
- **Sensitive fields stripped** — passwords, AWS keys, tokens, and secrets are redacted from API responses
- **Destructive operations gated** — delete, stop, and reboot require explicit `confirm: true`
- **No console.log** — all logging goes to stderr to avoid corrupting the MCP JSON-RPC stream on stdout