Skip to content
Guides

AI agents

Hand off whole workflows — verify members, restore a backup, post a panel — to an AI agent. Restore Hub supports three integration styles: native MCP, OpenAPI-aware platforms, and plain HTTP with a system prompt. Pick the one that matches your tool.

Bases an agent should know

  • REST API: https://api.restorehub.net/api/v1
  • OpenAPI: https://api.restorehub.net/api/v1/openapi.json
  • Data model: https://api.restorehub.net/api/v1/public/schema.json
  • MCP server: https://mcp.restorehub.net/mcp
  • Agent playbook: https://restorehub.net/agents.md

Native MCP clients

Best for Claude Desktop, Claude Code, Cursor, Zed — anything that speaks the Model Context Protocol. The agent gets a typed tool list pulled live from your account.

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json on macOS (or %APPDATA%\\Claude\\claude_desktop_config.json on Windows) and add:

{
  "mcpServers": {
    "restorehub": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.restorehub.net/mcp"],
      "env": {
        "RESTOREHUB_API_KEY": "rh_YOUR_KEY"
      }
    }
  }
}

Cursor

In Cursor, open Settings → MCP → Add new MCP server and paste:

{
  "name": "restorehub",
  "url": "https://mcp.restorehub.net/mcp",
  "headers": { "Authorization": "Bearer rh_YOUR_KEY" }
}

Full MCP setup including troubleshooting is on the MCP Server page.

OpenAPI-aware platforms

For ChatGPT custom GPTs, Vercel AI SDK, LangChain, or any tool that consumes an OpenAPI 3.x spec.

ChatGPT custom GPT

  1. Open Configure → Actions → Create new action
  2. Click Import from URL and paste https://api.restorehub.net/api/v1/openapi.json
  3. Set Authentication → API Key → Bearer and paste your rh_ key
  4. Save. The GPT can now call any endpoint.

Vercel AI SDK

import { generateText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { experimental_createMCPClient as createMCPClient } from "ai";

const mcp = await createMCPClient({
  transport: {
    type: "sse",
    url: "https://mcp.restorehub.net/mcp",
    headers: { Authorization: `Bearer ${process.env.RH_API_KEY}` },
  },
});

const tools = await mcp.tools();

const { text } = await generateText({
  model: anthropic("claude-sonnet-4-5"),
  tools,
  prompt: "Schedule daily backups at 03:00 UTC for all my servers.",
});

Plain HTTP + system prompt

For agents that have no native tool support — or when you want the simplest possible setup — give the model a system prompt that points at the OpenAPI and lets it construct HTTP calls.

# In your system prompt:
You manage Restore Hub via its REST API.

Base: https://api.restorehub.net/api/v1
Auth: Authorization: Bearer rh_YOUR_KEY

Always read the OpenAPI spec before constructing requests:
  https://api.restorehub.net/api/v1/openapi.json

Refer to the data model when interpreting responses:
  https://api.restorehub.net/api/v1/public/schema.json

Follow the playbook at:
  https://restorehub.net/agents.md

Refuse any operation that requires a scope your key doesn't have.
Confirm before destructive scopes (servers:delete, backups:restore,
members:pull, templates:apply, marketplace:payout, account:delete).

Widget SSO (drop-in Discord login)

Restore Hub's verification widget is a strict superset of rolling your own Discord OAuth. Drop in one script tag and you get a signed JWT plus the full Discord identity scope — username, global name, banner, accent color, locale, MFA status, Nitro tier, public flags, verified email, and account creation date.

Tokens are signed with RS256. The public JWKS is served at:

curl https://api.restorehub.net/api/v1/.well-known/jwks.json

Verify a widget JWT offline with any JWKS-aware library:

import { jwtVerify, createRemoteJWKSet } from "jose";

const JWKS = createRemoteJWKSet(
  new URL("https://api.restorehub.net/api/v1/.well-known/jwks.json")
);

const { payload } = await jwtVerify(token, JWKS, {
  issuer: "restorehub.net",
  audience: "restorehub:widget",
});
// JWT claims use compact names (flat). Map to full names if needed:
//   payload.sub  -> Discord user ID
//   payload.usr  -> username
//   payload.gn   -> globalName
//   payload.dsc  -> discriminator
//   payload.ava  -> avatar
//   payload.bnr  -> banner
//   payload.ac   -> accentColor
//   payload.loc  -> locale
//   payload.mfa  -> mfaEnabled
//   payload.prm  -> premiumType
//   payload.fl   -> publicFlags
//   payload.eml  -> email
//   payload.ev   -> emailVerified
//   payload.pv   -> phoneVerified
//   payload.cre  -> accountCreatedAt
//   payload.sid  -> Restore Hub server ID
//   payload.gid  -> Discord guild ID
// (HTTP verify-token endpoint, below, returns the same data with the full
// names AND nested under user.* — use whichever fits your codebase.)

Or POST the token to our HTTP endpoint (no API key required):

curl -X POST https://api.restorehub.net/api/v1/widget/verify-token \
  -H "Content-Type: application/json" \
  -d '{"token":"eyJhbGciOiJSUzI1NiIsImtpZCI6Im..."}'

Response shape (nested):

{
  "valid": true,
  "user": {
    "id": "1407504666643791972",
    "username": "alice",
    "globalName": "Alice",
    "discriminator": "0",
    "avatar": "abc123",
    "banner": null,
    "accentColor": null,
    "locale": "en-US",
    "mfaEnabled": true,
    "premiumType": 0,
    "publicFlags": 0,
    "email": "[email protected]",
    "emailVerified": true,
    "phoneVerified": null,
    "accountCreatedAt": "2025-08-19T23:21:02.700Z"
  },
  "serverId": "97aff4c6-1f12-41c0-ad9c-61ee2f9c7675",
  "discordGuildId": "1508506810271662190",
  "issuedAt": "2026-05-26T01:53:25.000Z",
  "expiresAt": "2026-05-26T02:53:25.000Z"
}

Identity fields live under user.*; token + server metadata are at the root. Failure cases return 401 with { error, code: "INVALID_TOKEN" }.

Full snippet generator + payload reference is in your dashboard under Servers → [server] → Widget.

Acting on the user's behalf — token exchange

The widget JWT proves identity but doesn't carry the underlying Discord OAuth credentials. If your backend needs to call the Discord API as the verified user — list their admin guilds, fetch their connections, sync linked-account profile data — exchange the widget JWT for their Discord access_token via POST /api/v1/widget/access-token:

curl -X POST https://api.restorehub.net/api/v1/widget/access-token \
  -H "Content-Type: application/json" \
  -d '{"token":"eyJhbGciOiJSUzI1NiIs..."}'

Response:

{
  "accessToken": "...",
  "refreshToken": "...",
  "expiresAt": "2026-06-02T01:23:45.000Z",
  "discordUserId": "1407504666643791972",
  "serverId": "97aff4c6-...",
  "tokenType": "Bearer"
}

Then call Discord directly:

curl https://discord.com/api/v10/users/@me/guilds \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Opt-in required. The server owner enables this in Dashboard → Widget → Webhook & Redirect → "Share Discord OAuth tokens with widget integrators". Off by default. Calling the endpoint without the toggle returns 403 ACCESS_TOKEN_SHARE_DISABLED with a message pointing the owner at the setting.

Errors: 400 bad body, 401 invalid JWT, 403 opt-in not enabled, 404 member or server gone, 429 rate-limited (60/min/IP), 500 decrypt failure (member must re-verify). Treat access tokens like any OAuth credential — TLS only, never log, store server-side not in browser storage. The JWT itself expires in 1h; the access_token in ~7 days; use the refresh_token to renew (see below).

Refreshing an expired access_token

Discord access tokens expire after ~7 days. Refreshing requires the OAuth app's client_id + client_secret which we hold, you don't. Proxy the refresh through POST /api/v1/widget/refresh-token — we exchange the refresh token against Discord on your behalf and return new ones:

curl -X POST https://api.restorehub.net/api/v1/widget/refresh-token \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "<refresh_token from earlier>",
    "serverId": "<serverId from earlier>"
  }'

Response:

{
  "accessToken": "...",
  "refreshToken": "...",          // Discord rotates — replace your stored copy
  "expiresAt": "2026-06-09T01:23:45.000Z",
  "scope": "identify email guilds guilds.join",
  "serverId": "97aff4c6-...",
  "tokenType": "Bearer"
}

Discord rotates the refresh_token on every refresh — store the returned one over the old. We also update our cached encrypted copy on the verified-member row so background workers stay in sync. Same opt-in gate (scopeAccessTokenShare) and rate limit (60/min/IP). If Discord rejects the refresh (token revoked, already used, etc.) you get 401 REFRESH_TOKEN_INVALID — the user needs to re-verify through the widget popup to mint fresh credentials.

1-click DNS via Domain Connect

For the per-domain TXT verification step (proving you own the site embedding the widget), Restore Hub supports the Domain Connect open standard. If your DNS provider supports it (today: Cloudflare, GoDaddy, IONOS, Google Domains via Cloudflare, and a handful of others), the dashboard shows an "Add via Cloudflare — 1 click" button. Click it, approve the record on your provider's screen, and we re-verify automatically when you return. The manual TXT copy-paste flow remains the fallback for everyone else.

Sample prompts

Drop these straight into Claude, Cursor, or any MCP-connected agent.

  • "List my Discord servers and show member counts."
  • "Set up verification on server [name] with VPN blocking and alt detection."
  • "Schedule daily backups at 3am UTC for every PRO server."
  • "Pull all verified members from server X to server Y."
  • "Mint an API key with only the read scopes I need to monitor my servers."
  • "Send a verification panel to the #verify channel on server [name]."
  • "Show me the last 20 audit-log entries with action containing 'BACKUP'."

Safety guardrails

Restore Hub doesn't trust agents — it trusts API keys. Two layers protect you:

  • Scopes. A key without backups:restore simply cannot restore a backup, no matter what an agent decides.
  • Audit log. Every API-driven action is recorded with the key ID and metadata. View at /dashboard/audit-log.

For agent-driven workflows we recommend minting a read-only key for the first few sessions, then unlocking write scopes once you trust the prompts.

AI Agents — Restore Hub | Restore Hub