Connect to MCP clients

Botverse uses the Model Context Protocol (MCP) with Streamable HTTP transport. Any MCP-compatible client can connect — Claude Desktop, Cursor, Continue.dev, or a custom agent.

MCP client support is evolving fast. The connector UI and config formats shown here reflect the state of each client as of May 2026. Claude, Cursor, and other clients are actively updating their MCP implementations — steps and screenshots may change. If something looks different, check the client's own docs and let us know so we can update this page.
The MCP endpoint is: https://botverse.cloud/mcp — works with any client that supports Streamable HTTP transport.

Claude.ai (web — recommended)

The fastest way to connect. Works in any browser — no software to install, no config files. Uses a short-lived connector token so your API key never appears in a URL.

Step 1 — generate your connector URL

Go to botverse.cloud/dashboard/api-keys and click Generate connector URL. This creates a 24-hour token and gives you a ready-to-paste URL in the format:

Your connector URL (from dashboard)
https://botverse.cloud/mcp?token=bv_sess_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
The token expires after 24 hours. Regenerate it from the dashboard any time — it takes one click and immediately revokes the old one. Your API key is unaffected.

Step 2 — add the connector in claude.ai

Go to claude.ai and open Customize → Connectors → +.

NameBotverse
Remote MCP server URLhttps://botverse.cloud/mcp?token=bv_sess_YOUR_TOKEN

Paste the URL you generated in Step 1. Leave OAuth fields blank. Click Add. Claude will connect and list all Botverse tools under Tool permissions.

Tool permissions default to "Needs approval". Each tool shows three states — auto-approve, needs approval, or disabled. Set them to auto-approve for hands-free agent workflows, or leave as "needs approval" to confirm each step.

Token expiry and reconnection

When a connector token expires (after 24 hours), claude.ai will show a connection error for Botverse tools. To reconnect: go to your dashboard, click Regenerate URL, then update the URL in your claude.ai connector settings. The whole flow takes about 30 seconds.

Claude Desktop

Claude Desktop supports MCP via a config file. Setup differs slightly between Mac and Windows.

Locate your config file

macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json
Linux~/.config/Claude/claude_desktop_config.json

macOS / Linux

Add the mcpServers entry to your config file:

claude_desktop_config.json
{
  "mcpServers": {
    "botverse": {
      "url": "https://botverse.cloud/mcp",
      "headers": {
        "X-API-Key": "bv_live_YOUR_KEY_HERE"
      }
    }
  }
}

Quit and relaunch Claude Desktop. In a new conversation, type: What tools do you have from Botverse? — Claude will list all five Botverse tools.

Windows

Windows Claude Desktop does not support the url config format directly. Use a small local bridge script instead — it starts instantly and proxies MCP messages to Botverse over HTTPS.

Step 1 — Install Node.js if you haven't already: nodejs.org. Version 18 or later required.

Step 2 — Create the bridge script. Save the following as C:\botverse-bridge.mjs, replacing bv_live_YOUR_KEY_HERE with your API key. The key goes in a header — not a URL — so it stays out of logs and history.

C:\botverse-bridge.mjs
import { createInterface } from "readline";

const API_KEY = "bv_live_YOUR_KEY_HERE";
const MCP_URL = "https://botverse.cloud/mcp";

const TOOLS = [
  { name: "get_upload_url", description: "Get a presigned S3 PUT URL to upload a source video or audio file.", inputSchema: { type: "object", properties: { filename: { type: "string" }, content_type: { type: "string" } }, required: ["filename", "content_type"] } },
  { name: "transcode_video", description: "Submit a video transcode job. Returns a job_id — poll get_job_status until complete.", inputSchema: { type: "object", properties: { object_key: { type: "string" }, output_format: { type: "string", enum: ["webm", "mov_prores", "mp3", "gif"] } }, required: ["object_key", "output_format"] } },
  { name: "get_job_status", description: "Poll the status of a transcode job. Call every 5 seconds until complete or failed.", inputSchema: { type: "object", properties: { job_id: { type: "string" } }, required: ["job_id"] } },
  { name: "get_download_url", description: "Get a presigned download URL for a completed job. URL expires in 24 hours.", inputSchema: { type: "object", properties: { job_id: { type: "string" } }, required: ["job_id"] } },
  { name: "get_wallet_balance", description: "Check your prepaid wallet balance.", inputSchema: { type: "object", properties: {}, required: [] } },
];

const rl = createInterface({ input: process.stdin, terminal: false });

rl.on("line", async (line) => {
  const trimmed = line.trim();
  if (!trimmed) return;
  let body;
  try { body = JSON.parse(trimmed); } catch { return; }
  const { method, id } = body;

  if (method === "initialize") {
    process.stdout.write(JSON.stringify({ jsonrpc: "2.0", id, result: { protocolVersion: "2024-11-05", capabilities: { tools: {} }, serverInfo: { name: "Botverse", version: "1.0.0" } } }) + "\n");
    return;
  }
  if (method === "tools/list") {
    process.stdout.write(JSON.stringify({ jsonrpc: "2.0", id, result: { tools: TOOLS } }) + "\n");
    return;
  }
  if (method?.startsWith("notifications/")) return;

  try {
    const res = await fetch(MCP_URL, { method: "POST", headers: { "Content-Type": "application/json", "X-API-Key": API_KEY }, body: trimmed });
    if (res.status === 204) return;
    process.stdout.write(await res.text() + "\n");
  } catch (e) {
    process.stdout.write(JSON.stringify({ jsonrpc: "2.0", id: id ?? null, error: { code: -32603, message: e.message } }) + "\n");
  }
});

Step 3 — Add to your Claude Desktop config:

%APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "botverse": {
      "command": "C:\\Program Files\\nodejs\\node.exe",
      "args": ["C:\\botverse-bridge.mjs"]
    }
  }
}
If Node.js is not at C:\Program Files\nodejs\node.exe, find the correct path by running where node in a terminal and update the command value accordingly.

Quit and relaunch Claude Desktop. Ask: What tools do you have from Botverse?

Test your first encode

Try a real job. Paste this into a Claude conversation:

I have a video at /Users/me/Desktop/keynote.mp4.
Please transcode it to WebM format using Botverse,
then give me the download URL.

Claude will call get_upload_url, upload the file, call transcode_video, poll for completion, and return a download link.

Costs are deducted at job completion, not submission. If a job fails, you are not charged. Check your balance any time by asking: What is my Botverse wallet balance?

Cursor

Cursor supports MCP in agent mode via the same config format as Claude Desktop (macOS).

~/.cursor/mcp.json
{
  "mcpServers": {
    "botverse": {
      "url": "https://botverse.cloud/mcp",
      "headers": {
        "X-API-Key": "bv_live_YOUR_KEY_HERE"
      }
    }
  }
}

After restarting Cursor, open Agent mode (Cmd/Ctrl + Shift + L). Botverse tools will be available to the agent when relevant to your request.

Continue.dev

Add Botverse as an MCP provider in your Continue config:

~/.continue/config.json
{
  "experimental": {
    "modelContextProtocolServers": [
      {
        "transport": {
          "type": "streamableHttp",
          "url": "https://botverse.cloud/mcp",
          "headers": {
            "X-API-Key": "bv_live_YOUR_KEY_HERE"
          }
        }
      }
    ]
  }
}

OpenAI / ChatGPT

OpenAI Assistants API (function calling)

OpenAI does not support MCP natively. Define Botverse tools as OpenAI function definitions and proxy the calls to the Botverse MCP endpoint.

OpenAI function definition — transcode_video
{
  "name": "transcode_video",
  "description": "Submit a video transcode job on Botverse. Source must first be uploaded via get_upload_url. Returns a job_id to poll with get_job_status.",
  "parameters": {
    "type": "object",
    "properties": {
      "object_key": {
        "type": "string",
        "description": "S3 object key from get_upload_url response"
      },
      "output_format": {
        "type": "string",
        "enum": ["webm", "mov_prores", "mp3", "gif"],
        "description": "Target output format"
      }
    },
    "required": ["object_key", "output_format"]
  }
}

Proxy function call to Botverse

When OpenAI calls a function, forward it to the Botverse MCP endpoint:

Node.js proxy (TypeScript)
async function callBotverseTool(toolName: string, args: Record<string, unknown>) {
  const res = await fetch("https://botverse.cloud/mcp", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": process.env.BOTVERSE_API_KEY!,
    },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "tools/call",
      params: { name: toolName, arguments: args },
    }),
  });
  const data = await res.json();
  return JSON.parse(data.result.content[0].text);
}

ChatGPT Plugins / GPT Actions

Build a thin REST wrapper around the Botverse MCP tools and expose it as an OpenAPI spec. Each Botverse tool becomes one API endpoint. GPT Actions call your wrapper, which calls Botverse. A full OpenAPI spec is available in the API reference.

Custom agents (bare HTTP)

Botverse uses standard JSON-RPC 2.0 over HTTP POST. Any HTTP client can call it — no MCP library required.

Tool discovery

List all available tools
curl -X POST https://botverse.cloud/mcp \
  -H "Content-Type: application/json" \
  -H "X-API-Key: bv_live_YOUR_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

Python example

botverse_client.py
import httpx, json, time

BOTVERSE_URL = "https://botverse.cloud/mcp"
BOTVERSE_KEY = "bv_live_YOUR_KEY"

def call_tool(name: str, arguments: dict) -> dict:
    response = httpx.post(
        BOTVERSE_URL,
        headers={"Content-Type": "application/json", "X-API-Key": BOTVERSE_KEY},
        json={"jsonrpc": "2.0", "id": 1, "method": "tools/call",
              "params": {"name": name, "arguments": arguments}},
        timeout=35,
    )
    result = response.json()
    if "error" in result:
        raise RuntimeError(result["error"]["message"])
    return json.loads(result["result"]["content"][0]["text"])

# Get upload URL
upload = call_tool("get_upload_url", {"filename": "video.mp4", "content_type": "video/mp4"})
print(upload["upload_url"])  # PUT your file here

# Submit transcode
job = call_tool("transcode_video", {"object_key": upload["object_key"], "output_format": "webm"})

# Poll for completion
while True:
    status = call_tool("get_job_status", {"job_id": job["job_id"]})
    if status["status"] == "complete": break
    if status["status"] == "failed": raise RuntimeError(status.get("error", "Job failed"))
    time.sleep(5)

# Get download URL
dl = call_tool("get_download_url", {"job_id": job["job_id"]})
print(dl["download_url"])

TypeScript / Node.js example

botverse.ts
const BASE = "https://botverse.cloud/mcp";
const KEY  = process.env.BOTVERSE_API_KEY!;

async function callTool<T>(name: string, args: Record<string, unknown>): Promise<T> {
  const res = await fetch(BASE, {
    method: "POST",
    headers: { "Content-Type": "application/json", "X-API-Key": KEY },
    body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "tools/call",
                           params: { name, arguments: args } }),
  });
  const data = await res.json();
  if (data.error) throw new Error(data.error.message);
  return JSON.parse(data.result.content[0].text) as T;
}

async function pollUntilComplete(jobId: string, intervalMs = 5000) {
  for (;;) {
    const s = await callTool<{ status: string }>("get_job_status", { job_id: jobId });
    if (s.status === "complete") return s;
    if (s.status === "failed")   throw new Error("Job failed");
    await new Promise(r => setTimeout(r, intervalMs));
  }
}
Set your HTTP client timeout to at least 35 seconds — the MCP server may take up to 30 seconds to respond while it enqueues a job. Polling calls are fast (under 1s).