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